آموزش جاوا اسکریپت مبتدی : ایجاد درخواستهای شبکه با جاوا اسکریپت
یکی دیگر از کارهای بسیار رایج در وبسایتها و برنامههای مدرن، ارسال درخواستهای شبکه برای بازیابی اقلام دادهای منفرد از سرور برای بهروزرسانی بخشهایی از یک صفحه وب بدون نیاز به بارگذاری کل یک صفحه جدید است. این جزئیات به ظاهر کوچک تأثیر زیادی بر عملکرد و رفتار سایتها داشته است، بنابراین در این مقاله، مفهوم آن را توضیح داده و به فناوریهایی که آن را ممکن میسازند، نگاهی خواهیم انداخت: به ویژه، Fetch API.
یک صفحه وب شامل یک صفحه HTML و (معمولاً) فایلهای مختلف دیگر، مانند stylesheets، اسکریپتها و تصاویر است. مدل پایه بارگذاری صفحه در وب این است که مرورگر شما یک یا چند درخواست HTTP برای فایلهای مورد نیاز برای نمایش صفحه به سرور ارسال میکند و سرور با فایلهای درخواستی پاسخ میدهد. اگر از صفحه دیگری بازدید کنید، مرورگر فایلهای جدید را درخواست میکند و سرور با آنها پاسخ میدهد.

این مدل برای بسیاری از سایتها کاملاً خوب کار میکند. اما وبسایتی را در نظر بگیرید که بسیار دادهمحور است. به عنوان مثال، وبسایت کتابخانهای مانند کتابخانه عمومی ونکوور. در میان چیزهای دیگر، میتوانید چنین سایتی را به عنوان رابط کاربری یک پایگاه داده در نظر بگیرید. ممکن است به شما امکان دهد ژانر خاصی از کتاب را جستجو کنید، یا ممکن است بر اساس کتابهایی که قبلاً قرض گرفتهاید، توصیههایی برای کتابهایی که ممکن است دوست داشته باشید به شما نشان دهد. وقتی این کار را انجام میدهید، باید صفحه را با مجموعه جدید کتابها برای نمایش بهروزرسانی کند. اما توجه داشته باشید که بیشتر محتوای صفحه - از جمله مواردی مانند سرصفحه، نوار کناری و پاورقی صفحه - ثابت میماند.
مشکل مدل سنتی در اینجا این است که ما باید کل صفحه را دریافت و بارگذاری کنیم، حتی زمانی که فقط نیاز به بهروزرسانی یک بخش از آن داریم. این ناکارآمد است و میتواند منجر به یک تجربه کاربری ضعیف شود.
بنابراین، به جای مدل سنتی، بسیاری از وبسایتها از APIهای جاوا اسکریپت برای درخواست داده از سرور و بهروزرسانی محتوای صفحه بدون بارگذاری صفحه استفاده میکنند. بنابراین وقتی کاربر محصول جدیدی را جستجو میکند، مرورگر فقط دادههایی را که برای بهروزرسانی صفحه لازم است درخواست میکند - برای مثال، مجموعهای از کتابهای جدید برای نمایش.

API اصلی در اینجا Fetch API است. این API به جاوا اسکریپت اجازه میدهد تا در یک صفحه اجرا شود و یک درخواست HTTP به سرور ارسال کند تا منابع خاصی را بازیابی کند. وقتی سرور آنها را فراهم میکند، جاوا اسکریپت میتواند از دادهها برای بهروزرسانی صفحه استفاده کند، معمولاً با استفاده از APIهای دستکاری DOM. دادههای درخواستی اغلب JSON هستند که فرمت خوبی برای انتقال دادههای ساختاریافته است، اما میتواند HTML یا فقط متن نیز باشد.
این یک الگوی رایج برای سایتهای دادهمحور مانند آمازون، یوتیوب، eBay و غیره است. با این مدل:
بهروزرسانیهای صفحه بسیار سریعتر انجام میشوند و لازم نیست منتظر بهروزرسانی صفحه باشید، به این معنی که سایت سریعتر و پاسخگوتر به نظر میرسد.
در هر بهروزرسانی دادههای کمتری دانلود میشود، به این معنی که پهنای باند کمتری هدر میرود. این ممکن است در یک دسکتاپ با اتصال پهنای باند زیاد مشکل بزرگی نباشد، اما در دستگاههای تلفن همراه و در کشورهایی که سرویس اینترنت پرسرعت فراگیر ندارند، یک مشکل اساسی است.
توجه: در روزهای اولیه، این تکنیک عمومی به عنوان جاوا اسکریپت و XML ناهمزمان (AJAX) شناخته میشد، زیرا تمایل به درخواست دادههای XML داشت. این روزها معمولاً اینطور نیست (احتمالاً JSON را درخواست خواهید کرد)، اما نتیجه هنوز یکسان است و اصطلاح "AJAX" هنوز هم اغلب برای توصیف این تکنیک استفاده میشود.
برای سرعت بخشیدن بیشتر به کارها، برخی سایتها هنگام درخواست اولیه، داراییها و دادهها را در رایانه کاربر ذخیره میکنند، به این معنی که در بازدیدهای بعدی، به جای دانلود نسخههای جدید هر بار که صفحه برای اولین بار بارگذاری میشود، از نسخههای محلی استفاده میکنند. محتوا فقط زمانی که بهروزرسانی شده باشد، از سرور بارگیری مجدد میشود.
در این بخش، چند مثال از Fetch API را بررسی خواهیم کرد.
مثالهای زیر از سطح پیچیدگی خاصی برخوردارند و نحوه استفاده از Fetch API را در برخی از زمینههای دنیای واقعی نشان میدهند.
برای این مثال، ما دادهها را از چند فایل متنی مختلف درخواست میکنیم و از آنها برای پر کردن یک قسمت محتوا استفاده میکنیم.
این سری از فایلها به عنوان پایگاه داده جعلی ما عمل میکنند؛ در یک برنامه واقعی، ما به احتمال زیاد از یک زبان سمت سرور مانند PHP، Python یا Node برای درخواست دادههای خود از یک پایگاه داده استفاده خواهیم کرد. با این حال، در اینجا میخواهیم آن را ساده نگه داریم و روی بخش سمت کلاینت این کار تمرکز کنیم.
برای شروع این مثال، یک کپی محلی از و چهار فایل متنی - و - با محتوای شعر مد نظر خودتان در یک دایرکتوری جدید در رایانه خود ایجاد کنید. در این مثال، وقتی یک بیت متفاوت از شعر (که ممکن است به خوبی آن را بشناسید) در منوی کشویی انتخاب شود، آن را دریافت خواهیم کرد.
درست داخل عنصر ، کد تابعی را داریم. این تابع ارجاعاتی به عناصر و را ذخیره میکند و یک شنونده (listener) به عنصر اضافه میکند، به طوری که وقتی کاربر مقدار جدیدی را انتخاب میکند، مقدار جدید به عنوان پارامتر به تابعی به نام ارسال میشود.
بیایید تابع خود را تعریف کنیم. اول از همه، کد زیر را زیر بلوک کد قبلی خود قرار دهید - این پوسته خالی تابع است.
ما تابع خود را با ساخت یک URL نسبی که به فایل متنی که میخواهیم بارگذاری کنیم اشاره میکند، شروع میکنیم، زیرا بعداً به آن نیاز خواهیم داشت. مقدار عنصر در هر زمان همان متن درون انتخاب شده است (مگر اینکه مقدار متفاوتی را در ویژگی مقدار مشخص کنید) - بنابراین به عنوان مثال "Verse 1". فایل متنی آیه مربوطه "" است و در همان دایرکتوری فایل HTML قرار دارد، بنابراین فقط نام فایل کافی است.
با این حال، سرورهای وب معمولاً به حروف کوچک حساس هستند و نام فایل فاصله ندارد. برای تبدیل "Verse 1" به "" باید 'V' را به حروف کوچک تبدیل کنیم، فاصله را حذف کنیم و "" را به انتها اضافه کنیم. این کار را میتوان با و template literal انجام داد. خطوط زیر را درون تابع خود اضافه کنید:
در نهایت، آمادهایم تا از Fetch API استفاده کنیم:
اینجا مطالب زیادی برای باز کردن وجود دارد.
اول، نقطه ورود به API مربوط به Fetch یک تابع سراسری به نام است که URL را به عنوان پارامتر میگیرد (یک پارامتر اختیاری دیگر برای تنظیمات سفارشی میگیرد، اما ما اینجا از آن استفاده نمیکنیم).
بعد، یک API ناهمزمان است که یک Promise برمیگرداند. اگر نمیدانید این چیست، ماژول مربوط به جاوا اسکریپت ناهمزمان و به ویژه درس مربوط به promiseها را بخوانید، سپس به اینجا برگردید. خواهید دید که آن مقاله نیز در مورد API مربوط به صحبت میکند!
بنابراین، از آنجا که یک promise برمیگرداند، ما یک تابع را به متد از promise برگشتی ارسال میکنیم. این متد زمانی فراخوانی میشود که درخواست HTTP پاسخی از سرور دریافت کرده باشد. در هندلر، بررسی میکنیم که درخواست موفق بوده است و اگر موفق نبوده باشد، خطا میدهیم. در غیر این صورت، را فراخوانی میکنیم تا بدنه پاسخ را به صورت متن دریافت کنیم.
معلوم میشود که نیز ناهمزمان است، بنابراین ما قولی را که برمیگرداند، برمیگردانیم و یک تابع را به متد این قول جدید منتقل میکنیم. این تابع زمانی فراخوانی میشود که متن پاسخ آماده باشد و درون آن بلوک خود را با متن بهروزرسانی میکنیم.
در نهایت، در انتها یک کنترلکننده را زنجیرهای میکنیم تا هرگونه خطایی را که در هر یک از توابع ناهمزمانی که فراخوانی کردهایم یا کنترلکنندههای آنها رخ میدهد، دریافت کند.
یکی از مشکلات مثال فعلی این است که هنگام بارگذاری اولیه، هیچ بخشی از شعر را نشان نمیدهد. برای رفع این مشکل، دو خط زیر را در پایین کد خود (درست بالای تگ پایانی ) اضافه کنید تا به طور پیشفرض بیت ۱ بارگذاری شود و مطمئن شوید که عنصر مثال خود را از یک سرور ارائه دهید
اگر مثال را فقط از یک فایل محلی اجرا کنید، مرورگرهای مدرن درخواستهای HTTP را اجرا نمیکنند. این به دلیل محدودیتهای امنیتی است (برای اطلاعات بیشتر در مورد امنیت وب، امنیت وبسایت را بخوانید).
برای حل این مشکل، باید مثال را با اجرای آن از طریق یک وب سرور محلی آزمایش کنیم.
در این مثال، ما یک سایت نمونه به نام فروشگاه کنسرو ایجاد کردهایم - این یک سوپرمارکت خیالی است که فقط کالاهای کنسروی میفروشد.
به طور پیشفرض، سایت تمام محصولات را نمایش میدهد، اما میتوانید از کنترلهای فرم در ستون سمت چپ برای فیلتر کردن آنها بر اساس دستهبندی، یا عبارت جستجو، یا هر دو استفاده کنید.
کدهای پیچیدهی زیادی وجود دارد که به فیلتر کردن محصولات بر اساس دستهبندی و عبارت جستجو، دستکاری رشتهها برای نمایش صحیح دادهها در رابط کاربری و غیره میپردازد. ما در این مقاله به همه آنها نمیپردازیم، اما میتوانید نظرات گستردهای را در کد پیدا کنید.
با این حال، کد Fetch را توضیح خواهیم داد.
اولین بلوکی که از Fetch استفاده میکند را میتوانید در ابتدای جاوا اسکریپت پیدا کنید:
تابع یک promise را برمیگرداند. اگر این کار با موفقیت انجام شود، تابع داخل اولین بلوک شامل پاسخی است که از شبکه برگردانده شده است.
در داخل این تابع ما:
بررسی میکنیم که سرور خطایی (مانند ) برنگردانده باشد. اگر چنین خطایی رخ داده باشد، خطا را ارسال میکنیم.
را روی پاسخ فراخوانی میکنیم. این کار دادهها را به عنوان یک شیء JSON بازیابی میکند. ما promise برگردانده شده توسط را برمیگردانیم.
در مرحله بعد، یک تابع را به متد از آن promise برگردانده شده ارسال میکنیم. به این تابع یک شیء حاوی دادههای پاسخ به صورت JSON ارسال میشود که آن را به تابع ارسال میکنیم. فرآیند نمایش تمام محصولات در رابط کاربری را آغاز میکند.
برای مدیریت خطاها، یک بلوک را به انتهای زنجیره متصل میکنیم. این تابع در صورتی اجرا میشود که promise به هر دلیلی با شکست مواجه شود. در داخل آن، یک تابع که به عنوان پارامتر ارسال میشود، یعنی یک شیء err، قرار میدهیم. این شیء err میتواند برای گزارش ماهیت خطای رخ داده استفاده شود، در این مورد ما این کار را با یک ساده انجام میدهیم.
با این حال، یک وبسایت کامل با نمایش یک پیام روی صفحه کاربر و شاید ارائه گزینههایی برای اصلاح وضعیت، این خطا را با ظرافت بیشتری مدیریت میکند، اما ما به چیزی بیش از یک ساده نیاز نداریم.
شما میتوانید خودتان حالت خطا را آزمایش کنید:
یک کپی محلی از فایلهای مثال ایجاد کنید.
کد را از طریق یک وب سرور اجرا کنید.
مسیر فایلی که فراخوانده میشود را به چیزی مانند '' تغییر دهید (مطمئن شوید که غلط املایی ندارد).
حالا فایل index را در مرورگر خود بارگذاری کنید (از طریق این تقریباً مشابه مورد قبلی عمل میکند، با این تفاوت که به جای استفاده از ، از استفاده میکنیم. در این مورد، میخواهیم پاسخ خود را به صورت یک فایل تصویری برگردانیم و قالب دادهای که برای آن استفاده میکنیم Blob است (این اصطلاح مخفف "Binary Large Object" است و اساساً میتواند برای نمایش اشیاء بزرگ شبیه فایل، مانند تصاویر یا فایلهای ویدیویی، استفاده شود).
پس از دریافت موفقیتآمیز blob، آن را به تابع خود ارسال میکنیم که آن را نمایش میدهد.
API مربوط به XMLHttpRequest
گاهی اوقات، به خصوص در کدهای قدیمیتر، API دیگری به نام XMLHttpRequest (که اغلب به اختصار "XHR" نامیده میشود) را خواهید دید که برای ارسال درخواستهای HTTP استفاده میشود. این API قبل از Fetch وجود داشته و در واقع اولین API بود که به طور گسترده برای پیادهسازی AJAX استفاده میشد. توصیه میکنیم در صورت امکان از Fetch استفاده کنید: این یک API سادهتر است و ویژگیهای بیشتری نسبت به XMLHttpRequest دارد. ما مثالی را که از XMLHttpRequest استفاده میکند، بررسی نمیکنیم، اما به شما نشان خواهیم داد که نسخه XMLHttpRequest از اولین درخواست can store ما چگونه خواهد بود:
پنج مرحله برای این کار وجود دارد:
یک شیء XMLHttpRequest جدید ایجاد کنید.
متد آن را برای مقداردهی اولیه فراخوانی کنید.
یک شنونده رویداد به رویداد بارگذاری آن اضافه کنید، که وقتی پاسخ با موفقیت تکمیل شد، اجرا میشود. در شنونده، را با دادهها فراخوانی میکنیم.
یک شنونده رویداد به رویداد خطای آن اضافه کنید، که وقتی درخواست با خطایی مواجه میشود، اجرا میشود.
درخواست را ارسال کنید.
همچنین باید کل آن را در بلوک قرار دهیم تا هرگونه خطایی که توسط یا ایجاد میشود را مدیریت کنیم.
امیدوارم فکر کنید که Fetch API نسبت به این بهبود یافته است. به طور خاص، ببینید که چگونه باید خطاها را در دو مکان مختلف مدیریت کنیم.
همیشه مقدار صحیح را نشان میدهد:
) و در کنسول توسعهدهنده مرورگر خود جستجو کنید. پیامی مشابه
خواهید دید.
بلوک دوم واکشی را میتوانید در داخل تابع
پیدا کنید: