مقدمه
تقریباً تمام اپلیکیشنهای وب مدرن نیاز دارند تا با یک سرور برای دریافت یا ارسال داده ارتباط
برقرار کنند. برای سالها، این کار با استفاده از شیء XMLHttpRequest (XHR) انجام میشد که سینتکس
پیچیده و غیرشهودی داشت. Fetch API جایگزین مدرن، قدرتمند و بسیار تمیزتر XHR است. این API یک
رابط کاربری مبتنی بر Promise برای ارسال و دریافت درخواستهای HTTP فراهم میکند و امروزه روش
استاندارد برای انجام این کار در جاوااسکریپت محسوب میشود.
fetch یک تابع سراسری است که در window (برای اسکریپتهای اصلی) و self (برای Web Workerها)
در دسترس است و کار با منابع شبکه را بسیار سادهتر میکند.
ارسال یک درخواست ساده (GET)
سادهترین کاربرد fetch، ارسال یک درخواست GET برای دریافت یک منبع است. این کار تنها با
فراخوانی fetch و پاس دادن URL منبع مورد نظر انجام میشود. نکته کلیدی در کار با fetch، درک
ماهیت دو-مرحلهای Promise آن است.
- Promise اول: متد fetch بلافاصله یک Promise برمیگرداند. این Promise به محض دریافت
هدرهای (headers) پاسخ از سرور، resolve میشود. مقدار حل شده، خود دادهی نهایی نیست، بلکه
یک شیء Response است که کل پاسخ HTTP را نمایندگی میکند.
- Promise دوم: برای دسترسی به بدنهی اصلی پاسخ (body)، باید یکی از متدهای خواندن بدنه را روی
شیء Response فراخوانی کنیم (مانند response.json() یا response.text()). این متدها نیز خودشان یک Promise برمیگردانند
که پس از دانلود و پردازش کامل بدنه، با دادهی نهایی resolve میشود.
JAVASCRIPT
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => {
console.log('Received response object:', response);
return response.json();
})
.then(data => {
console.log('Final data:', data);
})
.catch(error => {
console.error('Fetch Error:', error);
});
این کد یک درخواست به یک API نمونه ارسال میکند. در اولین .then شیء Response را دریافت و متد
.json() را برای خواندن بدنه فراخوانی میکنیم. در دومین .then به دادهی نهایی که یک شیء
جاوااسکریپت است، دسترسی داریم.
شیء Response و مدیریت خطا
شیء Response حاوی اطلاعات مفیدی درباره پاسخ سرور است، مانند status (کد وضعیت HTTP مثل 200 یا
404)، statusText (پیام وضعیت مثل "OK" یا "Not Found") و پراپرتی بسیار مهم ok.
یک نکته بسیار مهم و یکی از تلههای رایج در کار با fetch، نحوه مدیریت خطاهای HTTP است.
Promise مربوط به fetch تنها در صورتی reject میشود که یک خطای شبکهای رخ دهد (مانند عدم
اتصال به اینترنت). اگر سرور با یک کد وضعیت خطا مانند 404 (Not Found) یا 500 (Internal Server
Error) پاسخ دهد، از نظر fetch این یک تراکنش شبکهای "موفق" است و Promise آن resolve
میشود!
بنابراین، وظیفه ماست که به صورت دستی وضعیت پاسخ را بررسی کنیم. بهترین راه برای این کار، چک کردن
پراپرتی response.ok است. این پراپرتی تنها برای کدهای وضعیت موفق (در محدوده 200 تا 299) برابر
با true است. اگر false باشد، باید خودمان یک خطا throw کنیم تا توسط بلوک catch
گرفته شود.
JAVASCRIPT
async function fetchData(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
console.log('Successfully fetched data:', data);
} catch (error) {
console.error('Failed to fetch data:', error);
}
}
fetchData('https://jsonplaceholder.typicode.com/posts/1');
fetchData('https://jsonplaceholder.typicode.com/posts/999999');
این نسخه با استفاده از async/await خواناتر است و الگوی صحیح مدیریت خطا را نشان میدهد. چک
کردن response.ok و پرتاب کردن خطا در صورت ناموفق بودن پاسخ، یک الگوی استاندارد و ضروری در کار
با Fetch API است.
در این درس با اصول اولیه Fetch API برای ارسال درخواستهای GET و مدیریت پاسخها و خطاها آشنا
شدیم. این مهارت برای دریافت داده از سرورها ضروری است. در درس بعدی، «الگوهای رایج Fetch»، به
بررسی موارد پیشرفتهتری مانند ارسال داده با درخواستهای POST، تنظیم هدرها، و کار با دادههای
غیر-JSON خواهیم پرداخت.