קידוד URL

קידוד URL או קידוד באחוזים (באנגלית: URL Encoding) הוא שיטת קידוד תווים שמאפשרת להמיר כל מחרוזת טקסט למחרוזת שמכילה תווי ASCII חוקיים בלבד, בצורה שיתאפשר להשתמש בה בתור URI תקין, כגון כ-URL על גבי האינטרנט או כמזהה משאב אחיד (URN).

קידוד באחוזים מחליף תווי ASCII לא בטוחים, כדוגמת תווים ביוניקוד שאינם מופיעים ב-ASCII, עם הסימן "%" (אחוז) ולאחריו שתי ספרות הקסדצימליות. בנוסף, URL לא יכול להכיל רווחים, ולכן הקידוד יחליף אותם עם הסימן "+" (פלוס) או עם התווים "%20"<ref></ref>. 

כך למשל, המילים "" יוחלפו במחרוזת .

== קידוד אחוזים ב-URI ==
=== סוגים של תווים URI ===
התווים המותרים ב-URI הם שמורים או לא שמורים (או תו אחוז כחלק מהקידוד). תווים שמורים הן תווים שלפעמים יש להן משמעות מיוחדת. לדוגמה, התו לוכסן (<code>/</code>) משמש להפרדה בין חלקים שונים של כתובת URL (או באופן כללי יותר, URI). לתווים לא שמורים אין משמעויות מיוחדת, ובאמצעות קידוד אחוזים תווים שמורים מיוצגים באמצעות רצפי תווים מיוחדים. קבוצות התווים השמורים והלא שמורים והנסיבות שבהן יש משמעות מיוחדת לתווים שמורים מסוימים השתנו מעט עם כל עדכון של מפרטים השולטים ב-URI ובסכימות URI.
{| class="wikitable"
|+<nowiki>RFC 3986</nowiki> סעיף 2.2 תווים שמורים (ינואר 2005)
|<code>!</code>
|<code>#</code>
|<code>$</code>
|<code>&</code>
|<code>'</code>
|<code>(</code>
|<code>)</code>
|<code>*</code>
|<code>+</code>
|<code>,</code>
|<code>/</code>
|<code>:</code>
|<code>;</code>
|<code>=</code>
|<code>?</code>
|<code>@</code>
|<code>[</code>
|<code>]</code>
|}
{| class="wikitable"
|+<nowiki>RFC 3986</nowiki> סעיף 2.3 תווים לא שמורים (ינואר 2005)
|<code>A</code>
|<code>B</code>
|<code>C</code>
|<code>D</code>
|<code>E</code>
|<code>F</code>
|<code>G</code>
|<code>H</code>
|<code>I</code>
|<code>J</code>
|<code>K</code>
|<code>L</code>
|<code>M</code>
|<code>N</code>
|<code>O</code>
|<code>P</code>
|<code>Q</code>
|<code>R</code>
|<code>S</code>
|<code>T</code>
|<code>U</code>
|<code>V</code>
|<code>W</code>
|<code>X</code>
|<code>Y</code>
|<code>Z</code>
|-
|<code>a</code>
|<code>b</code>
|<code>c</code>
|<code>d</code>
|<code>e</code>
|<code>f</code>
|<code>g</code>
|<code>h</code>
|<code>i</code>
|<code>j</code>
|<code>k</code>
|<code>l</code>
|<code>m</code>
|<code>n</code>
|<code>o</code>
|<code>p</code>
|<code>q</code>
|<code>r</code>
|<code>s</code>
|<code>t</code>
|<code>u</code>
|<code>v</code>
|<code>w</code>
|<code>x</code>
|<code>y</code>
|<code>z</code>
|-
|<code>0</code>
|<code>1</code>
|<code>2</code>
|<code>3</code>
|<code>4</code>
|<code>5</code>
|<code>6</code>
|<code>7</code>
|<code>8</code>
|<code>9</code>
|<code>-</code>
|<code>_</code>
|<code>.</code>
|<code>~</code>
| colspan="13" |
|}
כל התווים האחרים ב-URI חייבים להיות מקודדים באחוזים.

=== תווים שמורים ===
כאשר לתו מהקבוצה של התווים השמורים יש משמעות מיוחדת בהקשר מסוים, וסכימת URI אומרת שיש צורך להשתמש בתו למטרה שאינה המטרה המיוחדת, אז התו חייב להיות מקודד באחוזים. קידוד אחוזים של תו שמור כולל המרת התו לערך הבתים המתאים לו ב-ASCII ולאחר מכן ייצוג ערך זה כזוג ספרות הקסדצימליות. הספרות, שלפניהן סימן אחוז (<code>%</code>) המשמש כתו בריחה, משמשות לאחר מכן ב-URI במקום התו השמור. (עבור תו שאינו ASCII, הוא מומר בדרך כלל לרצף הביטים שלו בUTF-8, ולאחר מכן כל ערך בתים מיוצג כמפורט לעיל)

לדוגמה, לתו השמור <code>/</code>, יש משמעות מיוחדת במקרה שנעשה בו שימוש בין רכיבי "נתיב" של URI, הוא מסמן תחימה של מקטעי נתיב. לפיכך, אם לפי סכימת URI נתונה, <code>/</code> צריך להיות בתוך קטע נתיב, אז יש להשתמש בתווים <code>%2F</code> או בתווים <code>%2f</code> בקטע במקום בתו <code>/</code>.
{| class="wikitable"
|+תווים שמורים לאחר קידוד אחוז
|<code>␣</code>
|<code>!</code>
|<code>#</code>
|<code>$</code>
|<code>%</code>
|<code>&</code>
|<code>'</code>
|<code>(</code>
|<code>)</code>
|<code>*</code>
|<code>+</code>
|<code>,</code>
|<code>/</code>
|<code>:</code>
|<code>;</code>
|<code>=</code>
|<code>?</code>
|<code>@</code>
|<code>[</code>
|<code>]</code>
|-
|<code>%20</code>
|<code>%21</code>
|<code>%23</code>
|<code>%24</code>
|<code>%25</code>
|<code>%26</code>
|<code>%27</code>
|<code>%28</code>
|<code>%29</code>
|<code>%2A</code>
|<code>%2B</code>
|<code>%2C</code>
|<code>%2F</code>
|<code>%3A</code>
|<code>%3B</code>
|<code>%3D</code>
|<code>%3F</code>
|<code>%40</code>
|<code>%5B</code>
|<code>%5D</code>
|}
תווים שמורים שאין להם מטרה שמורה בהקשר מסוים עשויים להיות מקודדים באחוזים אך אינם שונים מבחינה סמנטית מאלה שאינם.

ברכיב "שאילתה" של URI (החלק שאחרי תו ?), למשל, <code>/</code> עדיין נחשב לתו שמור אך בדרך כלל אין לו מטרה שמורה, אלא אם סכימת URI מסוימת אומרת אחרת. התו אינו צריך להיות מקודד באחוזים כאשר אין לו מטרה שמורה.

כתובות URI שההבדל היחידי שלהם הוא האם תו שמור מקודד באחוזים או מופיע באופן מילולי, נחשבים בדרך כלל לא שווים (המציינים את אותו משאב), אלא אם כן ניתן לקבוע שלתווים השמורים המדוברים אין מטרה שמורה. קביעה זו תלויה בכללים שנקבעו עבור תווים שמורים על ידי סכימות URI בודדות.

=== תווים לא שמורים ===
לעולם אין צורך בקידוד אחוזים של תווים מהקבוצה הבלתי שמורה.

URIs שנבדלים רק אם תו לא שמור מקודד באחוזים או מופיע באופן מילולי הם שווים בהגדרה, אך מעבדי URI, בפועל, עשויים שלא תמיד לזהות את השקילות הזו. לדוגמה, צרכני URI לא צריכים להתייחס ל-<code>%41</code> בצורה אחרת מהתו <code>A</code>או ל-<code>%7E</code> בצורה אחרת מ <code>~</code>, אבל יש כאלה שכן. למען יכולת פעולה הדדית מרבית, מפיקי URI אינם מעודדים קידוד אחוזים של תווים לא שמורים.

=== תו אחוז ===
מכיוון שתו האחוז ( <code>%</code>) משמש כסימן לספרות שקודדו באחוזים, עליו להיות מקודד באחוזים כמו <code>%25</code>כדי שתו זה ישמש כנתונים בתוך URI.

=== נתונים שרירותיים ===
רוב סכימות URI כוללות ייצוג של נתונים שרירותיים, כגון כתובת IP או נתיב מערכת קבצים, כרכיבים של URI. מפרטי סכימת URI צריכים, אך לרוב לא עושים זאת בפועל, לספק מיפוי מפורש בין תווי URI וכל ערכי הנתונים האפשריים המיוצגים על ידי התווים הללו.

==== נתונים בינאריים ====
מאז פרסום <nowiki>RFC 1738</nowiki> בשנת 1994 צוין כי סכמות המספקות ייצוג של נתונים בינאריים ב-URI חייבות לחלק את הנתונים לבייטים של 8 סיביות ולקודד באחוזים של כל בייט באותו אופן כמו לעיל. ערך בתים 0x0F, למשל, צריך להיות מיוצג על ידי <code>%0F</code>, אבל ערך בתים 0x41 יכול להיות מיוצג על ידי <code>A</code>, או <code>%41</code>. השימוש בתווים לא מקודדים עבור תווים אלפאנומריים ותווים אחרים שאינם שמורים מועדף בדרך כלל מכיוון שהוא גורם לכתובות URL קצרות יותר.

==== נתוני תווים ====
הפרוצדורה של קידוד נתונים בינאריים באחוזים הוחלפה לעיתים קרובות, לעיתים באופן לא הולם או מבלי שצוין במלואו, כדי להחיל על מחרוזות תווים. בשנות היצירה של ה-World Wide Web, כאשר עסקו בתווי נתונים בטבלת ה-ASCII והשתמשו בבתים המתאימים להם ב-ASCII כבסיס לקביעת רצפים שמקודדים באחוזים, תרגול זה היה יחסית לא מזיק; רק ההנחה הייתה שתווים ובייטים ממופים אחד לאחד וניתנים להחלפה. הצורך לייצג תווים מחוץ לטווח ASCII, לעומת זאת, גדל במהירות ותוכניות URI ופרוטוקולים לא הצליחו לספק כללים סטנדרטיים להכנת נתוני תווים להכללה ב-URI. כתוצאה מכך, יישומי אינטרנט החלו להשתמש במספר בתים שונים, תלויי מצב, וקידודים אחרים שאינם תואמים ASCII כבסיס לקידוד אחוזים, מה שמוביל לעמימות ולקושי לפרש URIs בצורה מהימנה.

לדוגמה, סכימות ופרוטוקולים רבים של URI המבוססים על RFCs 1738 ו-2396 מניחים שתווי הנתונים יומרו לבייטים לפי קידוד תווים לא מוגדר לפני ייצוג ב-URI על ידי תווים לא שמורים או בתים מקודדים באחוזים. אם הסכימה אינה מאפשרת ל-URI לספק רמז לגבי הקידוד שבו נעשה שימוש, או אם הקידוד מתנגש עם השימוש ב-ASCII לקידוד אחוזים שמורים ולא שמורים, אזי לא ניתן לפרש את ה-URI בצורה מהימנה. סכימות מסוימות אינן מסוגלות כלל להתייחס לקידוד, ובמקום זאת פשוט מציעות שתווי נתונים ממפות ישירות לתווי URI, מה שמותיר את המימושים להחליט אם וכיצד לקודד באחוזים תווי נתונים שאינם בסט השמורים או הלא-שמורים.
{| class="wikitable"
|+תווים נפוצים לאחר קידוד אחוז (מבוסס ASCII או UTF-8)
|<code>newline</code>
|<code>space</code>
|<code>"</code>
|<code>%</code>
|<code>-</code>
|<code>־</code>
|<code>.</code>
|<code><</code>
|<code>></code>
|<code>\</code>
|<code>^</code>
|<code>_</code>
|<code>`</code>
|<code>{</code>
|<code><nowiki>|</nowiki></code>
|<code>}</code>
|<code>~</code>
|<code>£</code>
|<code>円</code>
|-
|<code>%0A</code> או <code>%0D</code> או <code>%0D%0A</code>
|<code>%20</code>
|<code>%22</code>
|<code>%25</code>
|<code>%2D</code>
|<code>%D6%BE</code>
|<code>%2E</code>
|<code>%3C</code>
|<code>%3E</code>
|<code>%5C</code>
|<code>%5E</code>
|<code>%5F</code>
|<code>%60</code>
|<code>%7B</code>
|<code>%7C</code>
|<code>%7D</code>
|<code>%7E</code>
|<code>%C2%A3</code>
|<code>%E5%86%86</code>
|}
נתוני תווים שרירותיים מקודדים לפעמים באחוזים ומשמשים במצבים שאינם URI, כגון עבור תוכניות ערפול סיסמאות, או פרוטוקולי תרגום אחרים ספציפיים למערכת.

=== תקן נוכחי ===

תחביר ה-URI הגנרי ממליץ שסכימות URI חדשות המספקות ייצוג של נתוני תווים ב-URI צריכות, למעשה, לייצג תווים מהקבוצה הבלתי שמורה ללא תרגום, ועליו להמיר את כל שאר התווים לבייט<nowiki/>ים לפי UTF-8, ולאחר מכן לקודד באחוזים את הערכים האלה. הצעה זו הוצגה בינואר 2005 עם פרסום <nowiki>RFC 3986</nowiki>. סכמות URI שהוצגו לפני תאריך זה אינן מושפעות<ref></ref>.

המפרט הנוכחי לא מטפל במה לעשות עם נתוני תווים המקודדים. לדוגמה, במחשבים, נתוני תווים באים לידי ביטוי בצורה מקודדת, ברמה מסוימת, ולכן ניתן להתייחס אליהם כאל נתוני בינארי או תווים בעת מיפוי לתווי URI. ככל הנראה, זה תלוי במפרטי סכימת ה-URI לתת את הדעת על אפשרות זו ולדרוש כזו או אחרת, אבל בפועל, מעטים, אם בכלל, עושים זאת.

=== יישומים לא סטנדרטיים ===
קיים קידוד לא סטנדרטי עבור תווי יוניקוד:, כאשר xxxx היא יחידת קוד UTF-16 המיוצגת כארבע ספרות הקסדצימליות. התנהגות זו אינה מוגדרת על ידי אף RFC ונדחתה על ידי W3C<ref></ref>, המהדורה השמינית של ECMA-262 עדיין כוללת פונקציית <code>escape</code> שמשתמשת בתחביר זה, יחד עם <code>encodeURI</code> ו-<code>encodeURIComponent</code>, אשר מיישמות קידוד UTF-8 למחרוזת, ואז קידוד-באחוזים של הבתים המתקבלים<ref>https://www.ecma-international.org/ecma-262/8.0/index.html</ref>.

== בטפסי HTML ==
כאשר נתונים שהוזנו לטפסי HTML נשלחים, השמות והערכים של שדות הטופס מקודדים ונשלחים לשרת בהודעת בקשת HTTP באמצעות שיטות GET או POST. הקידוד המשמש כברירת מחדל מבוסס על גרסה מוקדמת של כללי הקידוד האחוזים הכלליים של URI<ref></ref>, עם מספר שינויים כגון נורמליזציה של שורה חדשה והחלפת רווחים ב-<code>+</code> במקום <code>%20</code>. סוג המדיה של הנתונים המקודדים בדרך זו הוא <code>application/x-www-form-urlencoded</code>, והוא מוגדר כעת במפרטי HTML ו- XForms. בנוסף, הדרישות של ה-CGI מכילים כללים לאופן שבו שרתי אינטרנט מפענחים נתונים מסוג זה והופכים אותם לזמינים ליישומים.

כאשר נתוני טופס HTML נשלחים בבקשת HTTP GET, הם נכללים ברכיב השאילתה של URI הבקשה באמצעות אותו תחביר שתואר לעיל. כאשר נשלח בבקשת HTTP POST או בדוא"ל, הנתונים ממוקמים בגוף ההודעה, והתגית <code>application/x-www-form-urlencoded</code> נכתבת ב-Content-Type של ה-header של ההודעה.

== קישורים חיצוניים ==
* [https://meyerweb.com/eric/tools/dencoder/ URL Decoder/Encoder], כלי לקידוד ופענוח של מחרוזות כתובות רשת (URL) מקידוד אחוזים לשפת מקור בה נכתב הקישור.
* [https://datatracker.ietf.org/doc/html/rfc3986#section-2.1 RFC3986], המפרט הטכני (RFC) של URI, ובתוכו המפרט של קידוד אחוזים.
== הערות שוליים ==

קטגוריה:כתובות רשת
קטגוריה:קידוד תווים
קטגוריה:מחרוזת (מדעי המחשב)