همه چیز دباره XHR  (AJAX , AXIOS , Fetch , …)

توی این مقاله میخوایم نگاهی به XHR که مخفف شده XMLHttpRequest است و کتابخانه های مربوط به اون بندازیم .به ساده ترین زبان ممکن XHR یک شئ در JavaScript و در سطح مرورگر است که پلی بین کلاینت و سرور برای ما ایجاد میکنه .مفهوم XHR برای اولین بار در internet explorer 5 معرفی شد و تبدیل به یکی از فناوری های کلیدی در پشت انقلاب Asynchronos JavaScript and XML یا همان Ajax شد و الان تقریبا یک عنصر اساسی برای وب سایت های مدرن است .قبل از XHR ، صفحات وب برای ارسال در خواست و گرفتن جواب از سرور ها مجبور بودن از اول بارگزاری بشن به همین صورتی که همین الان خیلی از وب سایت ها به همین شکل کار میکنن ، ولی وقتی XHR اومد باعث شد این روند عوض بشه .بالاتر گفتم که XHR یک پل ارتباطی بین کلاینت یا همون مروگر ها و سرور ایجاد میکنه ، این پل ارتباطی باعث میشه که مروگر ها به سرور درخواست بدن و جواب رو بگیرن بدون اینکه نیازی باشه مجدد بارگزاری بشن .قدرت XHR فقط به این نیست که باعث ارتباط بین سرور و کلاینت بدون رفرش میشه ، میشه گفت علاوه بر این خیلی از چیز های دیگرو هم هندل میکنه مثل :مرورگر برقراری ارتباط ، گرفتن اطلاعات و خاتمه دادن ارتباط را مدیریت میکنه .مرورگر بهترین HTTP(S) را تعیین میکند . (HTTP/1.0 , 1.1 , 2)مرورگر کش کردن ، redirect و content-type negotiation را انجام میدهد .مروگر محدودیت های امینیتی ، احراز هویت و حریم خصوصی را اعمال میکند .و یک سری موارد دیگه .توضیح مختصری در رابطه با APIبه طور خلاصه ، API پلی بین دو اپلیکیشن است و اجازه میده که دو اپلیکیشن با یکدیگر صحبت کنند .برای مثال من یک سایت دارم که کاربر میتونه داخلش ثبت نام انجام بده و از طرفی (چه رو سرور خودم چه رو یه سرور دیگه) یک فایل API دارم (زبان برنامه نویسی API مهم نیست هر چیزی میتونه باشه ) که رجیستر کاربر رو انجام میده و اگر مورد تایید بود اون کاربر رو به دیتابیس اضافه میکنه ، وقتی کاربر اطلاعات خودش رو تکمیل میکنه و روی گزینه ثبت نام میزنه ، توسط XHR این اطلاعات به سمت فایل API فرستاده میشن و در اونجا پردازش میشن ، بعد از اینکه پردازش انجام شد ، API یک پیام به سمت سایت میفرسته ، برای مثال میگه ثبت نام انجام شد و XHR این پیام رو دریافت میکنه و تنها کاری که سایت لازمه انجام بده اینه که پیام رو به صورت دلخواه برای کاربر به نمایش بزاره و تمام .خیلی ساده میتونید توی عکس روش کار API رو ببینیدپس میشه گفت یکی از کاربرد های بسیار مهم XHR این هست که توانایی استفاده از API ها بدون اینکه سایت دوباره بارگزاری بشه رو به راحتی به ما میده .یکی از ویژگی های مهمی که با استفاده از XHR به دست میاریم درست کردن سایت های SPA یا Single Page Aplication است که تماما بر اساس API و درخواست های XHR درست میشه .اگر بخواهیم XHR را در مرورگر ایجاد کنیم و درخواستی به API ارسال کنیم باید از روش زیر استفاده کرد :let request =new XMLHttpRequest(); request.open('GET' , 'https://www.example.com/example.php'); request.responseType ='text'; request.=function() { console.log(request.response); }; request.send();کد بالا یک کد جاوا اسکریپت است که وقتی صفحه وب سایت load شد ، درخواست XHR را به سمت API با متد GET ارسال میکند و وقتی جواب را در سمت سرور گرفت آن را در کنسول به نمایش میگذارد .در صورتی که میخواستیم پارامتر خاصی رو به طرف API ارسال کنیم (مثل مثالی که بالا تر برای ثبت نام کاربر زدم ) به صورت زیر پارامتر خودمون رو داخل یک استرینگ قرار میدیم و داخل request.send قرار میدیم :Let data = &quotname=kasra&lastname=habibbeygi&quot request.send(data);یک نکته بسیار جالب در رابطه با فرستادن اطلاعات در XHR وجود داره ، به این ماجرا توجه کنید :برای نوشتن یک API لازم نیست زبان برنامه نویسی خاصی رو مد نظر قرار بدیم ، هر زبانی که بتونه با دیتابیس در ارتباط باشه رو میتونیم استفاده کنیم مثلا یک API رو میتونیم با زبان هایی مثل PHP , python , node.js , ruby , java , … بنویسیم .حالا ممکنه براتون سوال پیش بیاد که داده ای که من توسط XHR ارسال میکنم باید با چه فرمتی باشه که هر کدوم از این زبان ها بتونن ساپورت کنن و بفهمن ؟جواب سوال JSON هست .فرمت JSON یا JavaScript Object Notation ، یک قالب سبک وزن برای ذخیره و انتقال داده هست ، شما با استفاده از این فرمت میتونید هر چیزی رو به صورت یک متن ذخیره کنید و انتقال بدید این فرمت هم برای انسان و هم برای ماشین خوانایی داره و تمام زبان های برنامه نویسی و اسکریپت نویسی قابلیت خواندن JSON رو دارن .نمونه یک سری اطلاعات که به صورت JSON نوشته شده اندپس ما معمولا پارامتر هامون رو به صورت یک استرینگ و نوشته متنی ارسال میکنیم یا با فرمت JSON .ولی همونطور که میبینید یک مقدار نوشتن XHR سخته (البته این فقط یک تیکه کد ساده است ، اگر نیاز باشه XHR رابه صورت حرفه ای نوشت خیلی سخت و پیچیده میشه) ، به همین خاطر تعداد زیادی کتابخانه برای نوشتن درخواست XHR به وجود اومدن که میتونن کار مارو خیلی ساده کنن .کتابخانه های معروف برای درخواست XHRجازگزین XHR خالص : () fetchخوبی این متد این است که نیازی به اضافه کردن کتابخانه خاصی نیست ، درواقع میشه گفت که یک جایگزین مدرن برای XHR است و شما میتونید خیلی راحت در کد های جاوااسکریپت سمت کلاینت ازش استفاده کنید .کد زیر دقیقا جایگزین کد بالا در XHR است "fetch('https://www.example.com/example.php', { method: 'GET', headers: { 'Accept': 'application/json, text/plain, */*', 'Content-Type': 'application/json' }, body: JSON.stringify({name : kasra , lastname : habibbeygi}) }).then(res =>res.json()) .then(res =>console.log(res));متد ajaxمتد محبوب ajax در کتابخانه بسیار پر کاربردjquery معرفی شد ، اگر شما در پروژه خودتون از jquery استفاده میکنید حتما پیشنهاد میکنم به جای fetch یا XHR از ajax استفاده کنید به خاطر اینکه هم خیلی اسون هست و هم اینکه jquery اون متد رو داخل خودش داره و نیازی نیست چیز جدیدی اضافه کنید ، تیکه کد بالا رو اگر بخواهیم با ajax بنویسیم به شکل زیر در می اید :Let data = “name=kasra&lastname=habibbeygi”; $.get(&quothttps://www.example.com/example.php&quot, data , function(res){ Console.log(res); })اگر توجه کنید میبینید که چقدر ساده تر از Fetch و XHR هست .کتابخانه AXIOSاین کتابخانه یک کتابخانه بر پایه promis برای node.js و سمت کلاینت است .تفاوت اصلی axios با بقیه کتابخانه ها در این است که هم در سمت سرور کاربرد دارد و هم در سمت کلاینت و جالب تر اینجاست که در هر دو سمت از کد های کاملا مشابه استفاده میشود .Let data = “name=kasra&lastname=habibbeygi”; axios.get(&quothttps://www.example.com/example.php&quot , data).then(function(res){ Console.log(res); })همانطوری که میبینید axios هم مثل jquery خیلی ساده هست .کتابخانه SuperAgent :یک کتاب خانه شبیه به axios است که محبوبیت زیادی هم در مرورگر ها هم در node.js داره .نکته جالب در superagent این هست که این کتابخانه توابع و متد های زیادی برای استفاده کردن داره .همچنین یک سری پلاگین برای نصب کردن داره که شما میتونید از قابلیت های اونها استفاده کنید ، برای مثال یک شبیه ساز rest API برای ما درست میکنه یا پلاگین های متنوع دیگه که هر کدوم استفاده خاص خودشون رو دارن .superagent.get(&quothttps://example.com/example.php&quot) .query({ name: 'kasra’, lastname: 'habibbeygi' }) .end((res) => { console.log(res); });اشتراک منابع متقابل یا Cross-Origin Resourse Sharing (CORS)بالا تر ما در رابطه با API ها صحبت کردیم و میدونیم که این API ها میتونن روی سرور خودمون و توسط خودمون نوشته شده باشن و یا روی یک سرور دیگه و توسط دیگران نوشته شده باشن و ما میتونیم به راحتی ازشون استفاده کنیم .حالا مشکل اینجاست که اگر API توسط یه شخص دیگه و روی یه سرور دیگه باشه ما به راحتی و با یه درخواست ساده میتونیم بهش متصل بشیم ؟جواب این سوال نه هست !چرا نه ؟ به خاطر اینکه تعدادی سیاست و قوانین امنیتی داخل مرورگر ها و سرور ها وجود داره تا وب سایت هارو از حملات مختلف در امان نگه داره ، این قوانین و سیاست های امنیتی رو CORS یا اشتراک منابع متقابل نام گزاری کردن .حفاظ امنیتی CORS به دو دسته کلایت ساید و سرور ساید تقسیم میشه .سمت کلاینتداخل مرورگر ها یه حفاظ امنیتی داریم به نام Same-origin policy که یه سری قوانین داره ، این قانون ها میگن که مقصد درخواست ما باید با منبعی که در ان هستیم یکی باشد و زمانی این دو یکی هستند که : به یک دامنه یا زیر دامنه متصل باشند . به یک پروتکل متصل باشند (HTTP / HTTPS) به یک پورت وصل باشند .این قوانین به خوبی در عکس زیر مشخص هستندکتابخانه های بالا که معرفی کردیم همگی از قوانین CORS پیروی میکنند و موقعی که درخواست را به سمت سرور ارسال کردن یک هدر Origin هم به درخواست HTTP اضافه میکنند که مقدار این هدر برابر با منبعی که درخواست از ان ارسال شده ، سرور درخواست شما را دریافت میکند ، هدر origin را میخواند تا متوجه شود درخواست از کجا آمده .وقتی فایل API روی سرور خود سایت قرار داشته باشه میشه گفت CORS درخواستی رو بلاک نمیکنه و همه چیز اوکیه ولی وقتی از سایت بخوایم به یه API روی یه سرور دیگه درخواست بدیم CORS برامون محدودیت های بالا رو ایجاد میکنه و برای رفع این محدودیت ها باید به درخواست کننده مجوز درخواست داده بشه .سمت سرورسمت سرور و داخل API شما میتوانید از یک سری header استفاده کنید که این درخواست ها را مدیریت کنید .هدر های Access-Control این قابلیت را به شما میدهند .اگر شما این هدر را به API خود اضافه نکنید ، تمام درخواست های Cross-Origin بلوکه میشوند .تعداد هدر های Access-Control بسیار زیاد هستند ولی یکی از این هدر ها بسیار مهم است ، شما با این هدر مجوز دسترسی را صادر میکنید :اگر به جای آدرس دامنه از * استفاده کنید به تمام درخواست ها ، مجوز داده میشود .سخن پایانی به وجود آمدن XHR باعث تحول بزرگی در وب سایت ها شد و توانایی استفاده و درست کردن چیز های جدید مثل استفاده از API ، درست کردن PWA و SPA ، ماکروسرویس و ... رو به ما داد .پیشنهاد میکنم اگر شما هم برنامه نویس سایت هستید و هنوز به این ماجرا روی نیاوردید و ازش استفاده نمیکنید ، حتما نظرتون رو عوض کنید ، به خاطر اینکه دستتون رو توی زمینه های مختلفی باز میکنه و باعث میشه ساختار شما ، ساختار منظم تری باشه و خیلی چیز های دیگه ...منابع : اگر اطلاعات کامل تر و بیشتری در رابطه با XHR نیاز دارید حتما به سایت زیر یه سری بزنید : https://www.oreilly.com/library/view/high-performance-browser/9781449344757/ch15.html عکس های گیف : https://www.roxo.ir/cs-visualized-cors