رمزگذاری و رمزگشایی URL، توضیح برای توسعهدهندگان
یک فاصله در URL تایپ کنید، یا یک کلمه به خط سیریلیک، یا علامت & که به داده شما تعلق دارد نه به خود آدرس، و باید راه حلی وجود داشته باشد. وب تنها انتقال ایمن مجموعه کوچک و قابل پیشبینی از کاراکترهای ASCII را تضمین میکند. هر چیز دیگری باید در قالبی که روترها، سرورها و مرورگرها همه بر آن توافق دارند پیچیده شود. این قالب percent-encoding است که رایجتر رمزگذاری URL نامیده میشود، و این صفحه به شما امکان میدهد متن را در هر دو جهت مستقیماً در مرورگرتان تبدیل کنید.

percent-encoding واقعاً چیست
قانون مکانیکی است و پیروی از آن آسان. هر کاراکتری که نمیتواند به صورت تحتاللفظی ظاهر شود با یک علامت % و دو رقم هگزادسیمال که مقدار بایت آن کاراکتر را بیان میکنند جایگزین میشود. فاصله به %20 تبدیل میشود. علامت + به %2B. علامت # به %23. وقتی یک کاراکتر به چند بایت نگاشته میشود، مثل اکثر متنهای غیر ASCII زیر UTF-8، به سادگی چند سهتایی پشت سر هم میگیرید: علامت یورو به %E2%82%AC تبدیل میشود. رمزگشایی فرایند را معکوس میکند و هر سهتایی را به بایت اصلی خود برمیگرداند.
این قرارداد در مشخصه URI (RFC 3986) تعریف شده و عمداً خستهکننده است. خستهکننده بودن هدف است. هر کلاینت و سرور HTTP خوشرفتاری روی کره زمین قوانین یکسانی پیادهسازی میکند، بنابراین یک لینک که در یک جا درست رمزگذاری شده در همه جای دیگر سالم میرسد.
چرا باید وجود داشته باشد
URL دو نوع کاراکتر با کارهای بسیار متفاوت حمل میکند. کاراکترهای رزرو شده مثل /، ?، #، &، = و : ساختاری هستند. آنها به یک تجزیهکننده میگویند کجا مسیر تمام میشود و رشته query آغاز میشود، یا یک پارامتر کجا متوقف میشود و بعدی شروع. اگر داده واقعی شما یکی از این نمادها را داشته باشد، باید رمزگذاری شود تا تجزیهکننده آن را با علائم نگارشی اشتباه نگیرد. یک شماره سفارش مثل A&B/2024 که مستقیماً در یک query string قرار گیرد به عنوان دو پارامتر و یک بخش مسیر خوانده میشود.
سپس کاراکترهای ناایمن و غیر ASCII وجود دارند: فاصلهها، نقلقولها، براکتهای زاویهای، حروف تکیهدار، ایموجی، هر چیزی خارج از محدوده ASCII ساده. اینها به صورت تحتاللفظی در URL جایی ندارند، چه به این دلیل که در انتقال آسیب میبینند چه به این دلیل که نمایش تعریفشدهای ندارند. رمزگذاری آنها لینکها را تمیز و قابل پیشبینی نگه میدارد به جای اینکه نتیجه را به شانس واگذار کند.
کجا در کار واقعی با آن مواجه میشوید
رشتههای query نمونه کلاسیک هستند. هر مقداری که به ?key=... اضافه میکنید باید رمزگذاری شود تا ورودی کاربر نتواند ساختار را بشکند. همین برای ارسال فرمهای HTML به صورت application/x-www-form-urlencoded صدق میکند، جایی که مرورگر مقادیر فیلد را به صورت خودکار رمزگذاری میکند (و بر اساس قرارداد تاریخی، فاصلهها را به + تبدیل میکند نه %20). همچنین هنگام ساختن لینکهایی که به صفحات با عنوانهای غیر لاتین اشاره میکنند، هنگام ساختن درخواستهای API به صورت دستی، هنگام انتقال اهداف بازگشت به عنوان پارامترها، و هنگام اشکالزدایی از اینکه چرا درخواستی که در نوار آدرس درست به نظر میرسد در سرور خراب میرسد با آن روبرو میشوید.

encodeURI در برابر encodeURIComponent
JavaScript دو رمزگذار ارائه میدهد و انتخاب اشتباه یک باگ رایج است. تفاوت در محدوده است. encodeURIComponent برای یک تکه داده مثل یک مقدار query است. تقریباً همه چیز را رمزگذاری میکند، از جمله کاراکترهای رزرو شده /، ?، :، @، &، =، + و #. این دقیقاً همان چیزی است که میخواهید وقتی داده مجاز است این نمادها را به عنوان متن معمولی داشته باشد.
encodeURI برای یک آدرس کامل است که قصد دارید کار کند. کاراکترهای ساختاری را دست نخورده میگذارد، بنابراین اسلشها، دونقطهها و علامتهای سوال که URL را کنار هم نگه میدارند دوام میآورند. از آن استفاده کنید وقتی یک URL کامل دارید و فقط میخواهید فاصلهها یا کاراکترهای غیر ASCII را پاکسازی کنید؛ برای encodeURIComponent دست دراز کنید هر وقت مقداری را در یک URL بزرگتر درج میکنید. یک قانون ساده: کل لینک را با encodeURI رمزگذاری کنید، قطعاتی که درج میکنید را با encodeURIComponent.
همه چیز روی دستگاه شما میماند
این ابزار کاملاً در مرورگر شما اجرا میشود. متنی که الصاق میکنید به صورت محلی با همان روتینهای استاندارد رمزگذاری یا رمزگشایی میشود و هرگز به سرور نمیرود، که برای توکنها، پارامترهای امضاشده یا هر چیز دیگری که ترجیح میدهید روی سیم نفرستید ایمن است. اگر با تبدیلهای متنی دیگر کار میکنید، مبدل Base64 درست کنارش قرار دارد، و میتوانید مجموعه کامل ابزارهای توسعهدهنده را برای کمکهای روزمره بیشتر مرور کنید.
پرسشهای متداول
%20 در یک URL به چه معناست؟
یک فاصله رمزگذاریشده است. کاراکتر فاصله به صورت تحتاللفظی در URL مجاز نیست، بنابراین با یک علامت درصد و مقدار هگزادسیمال ۲۰ که مقدار بایت فاصله است جایگزین میشود.
چرا گاهی به جای %20 علامت + میبینم؟
داده فرم HTML از نوع application/x-www-form-urlencoded فاصلهها را بر اساس قرارداد تاریخی به صورت علامت + رمزگذاری میکند. در یک مسیر یا query معمولی، فاصله به صورت %20 رمزگذاری میشود. هر دو در زمینه مناسب به فاصله برمیگردند.
چه زمانی باید از encodeURIComponent به جای encodeURI استفاده کنم؟
از encodeURIComponent برای یک مقدار منفرد که در URL درج میکنید مثل یک پارامتر query استفاده کنید، چون کاراکترهای رزرو شده را هم رمزگذاری میکند. از encodeURI برای یک آدرس کامل استفاده کنید وقتی میخواهید اسلشها، دونقطهها و علامتهای سوالی که آن را کنار هم نگه میدارند حفظ شوند.
آیا رمزگذاری URL معنای دادهام را تغییر میدهد؟
خیر. رمزگذاری کاملاً برگشتپذیر است. رمزگشایی نتیجه دقیقاً متن اصلی را بایت به بایت برمیگرداند، تا زمانی که از هر دو طرف از مجموعه کاراکتر یکسانی استفاده شود.
کاراکترهای غیر ASCII مثل حروف تکیهدار یا ایموجی چگونه مدیریت میشوند؟
ابتدا به بایتهای UTF-8 تبدیل میشوند، سپس هر بایت سهتایی درصد خودش میشود. بنابراین یک حرف تکیهدار یا ایموجی میتواند در خروجی رمزگذاریشده به چند سهتایی گسترش یابد.
آیا هنگام استفاده از این ابزار متنم به سرور ارسال میشود؟
خیر. رمزگذاری و رمزگشایی کاملاً در مرورگر شما انجام میشوند. هیچ چیزی که الصاق میکنید آپلود نمیشود، بنابراین استفاده با رشتههای خصوصی یا حساس ایمن است.
