آبجکت کد شده به جای URL Query Parameterها در جاوا اسکریپت?


اکثر برنامه نویس ها تجربه دست و پنجه نرم کردن به Query Parameterها و یا همون متغیرهای موجود توی URL رو توی مرورگر داشتند. موقعی که میخواید با استفاده از این متغیرها، مقادیری رو دریافت کنید و با ازای اون ها محتوای مرتبط رو توی صفحتون نشون بدید و یا درخواستی رو به سمت سرور خودتون بفرستید.
بذارین توضیح این مطلب رو با یه مقدمه و مثال شروع کنیم:

فرض کنین یک صفحه ی جستجو دارین به آدرس yourwebsite.com/search و یک سری فیلتر. در ابتدا که این صفحه رو باز کنید کلیه محصولات برای شما به نمایش در میاد. حالا می خواید یه سری فیلتر اعمال کنید و محصولات مورد نظرتون رو محدود کنید. مثلا تمامی محصولات با قیمت بین ۱۰۰ هزار تا ۲۰۰ هزار تومن. به طور معمول URL شما به این شکل در میاد:
yourwebsite.com/search?minPrice=100000&maxPrice200000. خوب تا این جا مسئله ی خاصی نیست. توی کدتون میاین چیکار میکنید؟ نهایتا پارامترهای minPrice و maxPrice رو جداگونه میگیرید و درخواست خودتون رو به سرور میفرستید و محصولات توی این رنج قیمت رو بر میگردونید.
حالا فرض کنید که تعداد فیلترها زیاد بشن. شما یه همچین URLی رو میبینید:
yourwebsite.com/search?minPrice=100000&maxPrice=200000&sortBy=1&isImage=true&color=red&type=1&isAvailable=true&minSize=10&maxSize=20
خب اینجا یکم URL شما زشت شده اما از دید برنامه نویسی بازم زیاد مسئله ای نیست و نهایتا چند خط کد دیگه به کداتون اضافه میشه!

-- آدرس بالا یه نکته داره!

یه جایی اون بین نوشتیم color=red. این یعنی محصولاتی که قرمز رنگ هستن رو بیار! اما اگه کاربر بخواد چندتا محصول با رنگ های درخواستی رو بیاره چی؟! مثلا تمام محصولاتی که قرمز، بنفش یا آبی هستن؟!

به عبارت دیگه میخوایم یک آرایه رو سرچ کنیم به صورتی که color=[red, purple, blue] باشه. این رو چجوری توی URL میارین؟!



اگر یکم سرچ کنین پکیج هایی برای هندل کردن اینجوری Query Parameter ها هست.
مثل:

https://www.npmjs.com/package/query-string
https://www.npmjs.com/package/qs

که میان یه آبجکت از شما میگیرن و اون رو تبدیل به اینجور Query Stringها می کنن. واسه مثال
color میشه یه همچین چیزی: color[0]=red&color[1]=purple&color[2]=blue

خب مسلما هرچی آبجکت شما سنگین تر بشه این عبارت ها طولانی تر میشن. و همون طور که میبینین کلمه colorبه تعداد آیتم های آرایه داره تکرار میشه!

حالا فرض کنین یه آبجکت یا آرایه تو در تو داشته باشین! تقریبا یه فاجعه توی URL بوجود میاد! حتی ممکنه شما نخواین کس دیگه ای پارامترهای شما رو ببینه و بخونه!

آیا مهمه واسه کاربر که این فیلترها رو ببینه؟؟

خب اینجاس که یه روش دیگه به کار میاد. من اینجا یه توضیح مختصر از چگونگی این کار رو میگم و یکم هم کد بهتون نشون میدم و تصمیم گیری رو به عهده خودتون میذارم.

روش دیگه اینه که اون آبجکت اولیه ای که داریم رو یجوری به String اینکد شده تبدیل کنیم و بعد بتونیم با parse کردن اون String به طور مستقیم به محتواش دست پیدا کنیم. یعنی نیازی نباشه یک URL با تعداد زیادی & داشته باشیم و متغیرهای تکراری رو توش ببینیم.

واسه این کار یه سری پکیج هست که من یکیش رو بهتون معرفی میکنم و میگم که چرا انتخابش کردم.
اسم پکیج json-url هست و لینکش رو اینجا میتونید پیدا کنید.

کاری که این پکیج میکنه اینه که آبجکت شما رو میگیره با یه سری الگوریتم که خودتونم می تونید انتخاب کنید اون رو Encrypt میکنه و بعد هم امکان Decrypt کردن رو بهتون میده.

اگه توی Nodejs دارین کد میزنید که این پکیج رو import کنید و راحت استفاده کنید. اگه سمت کلاینت می-خواین استفاده کنین این مراحل رو برید.

۱- این فایل ها رو از توی دموی پکیج دانلود کنید:
json-url-lzma.js، json-url-msgpack.js، json-url-safe64.js
۲- فایل پکیج رو توی HTML اضافه کنید:‌
<script src="/js/jsonUrl.js"></script>

حالا به این شکل می تونید ازش استفاده کنید:

const lib = window.JsonUrl('lzma') // Client side
const lib = require('json-url')('lzma') // Server side
lib.compress(object).then(compressed => {//your logic})
lib.decompress(string).then(decompressed => {//your logic})

در نهایت شما توی آدرس بار مرورگرتون فقط یه همچین چیزهایی میبینین:
yourwebsite.com/search?query1=1ky0RJLPRl7263SDA_asdAsBB23s

دلیل اینکه من این پکیج رو برای Encode کردن استفاده کردم پشتیبانی خیلی عالی از کاراکترهای UTF-8 هست یعنی اگر توی آبجکتتون کلمه فارسی هم داشته باشین هم سمت سرور هم سمت کلاینت به خوبی Encode میشه. چیزی که من با بقیه روش ها به مشکل میخوردم.

خوبیه دیگش اینه که شما میتونید Query Parameterهای دیگه هم اضافه کنید هرجور که میخواین. توی URL بالا ما فقط یه دونه متغیر وجود داره که اسمش query1 هست. شما می تونید باز هم آبجکت استفاده کنین با یک متغیر دیگه که در روش قبل حداقل به راحتی ممکن نبود.

من یه helper ساده نوشتم واسه این کار که isomorphic هست یعنی واسه اپلیکیشن هایی که SSR هم دارن راحت استفاده میشه (توجه کنید که lzma اسم الگوریتم Encryptهست):

var codec = require('json-url')('lzma')

export const urlCompress = (obj) => { 
      if (typeof window !== 'undefined' && window.document) {  
         const lib = window.JsonUrl('lzma')  return lib.compress(obj) 
      } else { 
          return codec.compress(obj)  }
}
 
export const urlDecompress = (string) => { 
       if (typeof window !== 'undefined' && window.document) {
           const lib = window.JsonUrl('lzma')  return lib.decompress(string)
        } else {  return codec.decompress(string)  } 
}  
      

اگر مطلب رو دوست داشتید لطفا ❤️ فراموش نشه!! مرسی!