دریافت داده با Fetch
تابع fetch(url) از مرورگر میخواهد یک درخواست HTTP بفرستد. خروجی فوری آن Promise است؛ این Promise معمولاً به یک Response میرسد، نه به JSON پردازششده.
اول Response، بعد داده
با await fetch(...) به وضعیت، headerها و جریان بدنهٔ پاسخ دسترسی پیدا میکنیم. response.json() متن بدنه را میخواند، آن را بهصورت JSON parse میکند و Promise دیگری میدهد که نتیجهاش دادهٔ JavaScript است.
دو مرحلهٔ جدا
دریافت پاسخ و تبدیل بدنه را دو کار جدا در نظر بگیرید. ممکن است status پاسخ مهم باشد، اما بدنه اصلاً JSON نباشد.
📊 از درخواست تا داده
| عبارت | نتیجه | مفهوم |
|---|---|---|
| fetch(url) | Promise<Response> | درخواست آغاز شده است |
| await fetch(url) | Response | status، headerها و جریان بدنه |
| response.json() | Promise<any> | خواندن و parse کردن بدنه |
| await response.json() | دادهٔ JavaScript | آبجکت یا مقدار parseشده |
خروجی fetch یک Promise است
این قطعه برای مستقلبودن از Blob URL استفاده میکند و فقط نوع خروجی را نشان میدهد. Blob URL منبعی موقت در حافظهٔ مرورگر است، نه endpoint هممبدأ روی سرور.
const blob = new Blob(['{"drink":"lida tea"}'], { type: "application/json" });
const url = URL.createObjectURL(blob);
const ticket = fetch(url);
console.log(ticket instanceof Promise);
ticket.finally(() => URL.revokeObjectURL(url));
خروجی true است. در برنامهٔ واقعی میتوان Blob URL را با یک مسیر HTTP مانند /data/drink.json عوض کرد.
اول Response، سپس JSON
نمونهٔ بعد همان منبع محلی را میسازد و هر دو مرحله را await میکند.
async function loadDrink() {
const blob = new Blob(['{"drink":"lida tea"}'], { type: "application/json" });
const url = URL.createObjectURL(blob);
try {
const response = await fetch(url);
if (!response.ok) throw new Error("HTTP " + response.status);
const data = await response.json();
console.log(data.drink);
} finally {
URL.revokeObjectURL(url);
}
}
loadDrink();
خروجی lida tea است. اگر فایل واقعی /data/drink.json داشته باشیم، محتوای آن میتواند {"drink":"lida tea"} باشد و روش خواندن تغییری نمیکند.
خطای HTTP را صریح بررسی کنید
fetch معمولاً برای پاسخ HTTP با status برابر 404 یا 500 reject نمیشود. قطع شبکه میتواند Promise را رد کند، اما status ناموفق بهتنهایی معمولاً چنین کاری نمیکند. response.ok یا response.status را بررسی کنید.
const response = new Response("Not found", {
status: 404,
statusText: "Not Found"
});
console.log(response.ok);
console.log(response.status);
پاسخ ساختهشده ابتدا false و سپس 404 را نشان میدهد؛ اینها همان ویژگیهایی هستند که بعد از fetch واقعی میخوانیم. بدنهٔ خطا را فقط وقتی با json() بخوانید که API واقعاً JSON برگرداند.
json نیز Promise میدهد
فراخوانی json() خواندن و parse کردن بدنه را بهصورت ناهمگام آغاز میکند.
const response = new Response('{"drink":"lida tea"}', {
headers: { "Content-Type": "application/json" }
});
const dataPromise = response.json();
console.log(dataPromise instanceof Promise);
dataPromise.then(data => console.log(data.drink));
خروجی true است. پس از await response.json()، متغیر data یک آبجکت JavaScript است و data.drink رشتهٔ موردنظر را دارد.
دموی صفحه بدون وابستگی به endpoint
این دمو یک Blob URL را fetch میکند تا به مسیر واقعی وابسته نباشد. جریان کار API و status برابر 200 را نشان میدهد، اما درخواست سرور نیست.
<!DOCTYPE html>
<html>
<body>
<p id="cup">blank</p>
<p id="line">…</p>
<script>
async function load() {
const blob = new Blob(['{"drink":"lida tea"}'], { type: "application/json" });
const url = URL.createObjectURL(blob);
try {
const response = await fetch(url);
if (!response.ok) throw new Error("HTTP " + response.status);
const data = await response.json();
document.getElementById("cup").textContent = data.drink;
document.getElementById("line").textContent =
response.status + " / " + data.drink;
} finally {
URL.revokeObjectURL(url);
}
}
load();
</script>
</body>
</html>
صفحه 200 / lida tea را نشان میدهد. در پروژهٔ واقعی از URL مبتنی بر HTTP استفاده کنید و پیش از parse کردن، همان بررسی ok را نگه دارید.
تمرین
روی یک سرور محلی فایل /data/drink.json بسازید و Blob URL را با مسیر آن عوض کنید. سپس مسیر ناموجودی را درخواست کنید و ok و status را مقایسه کنید.
اشتباههای رایج
Promise برگشتی از fetch را با داده اشتباه نگیرید. فراخوانی و await کردن json() را فراموش نکنید. برای تشخیص هر 404 فقط به catch تکیه نکنید.
جمعبندی
fetch درخواست میفرستد و Promiseای میدهد که به Response میرسد. ابتدا ok را بررسی کنید، سپس بدنهٔ مورد انتظار را بخوانید. response.json() نیز Promise دادهٔ JavaScript را برمیگرداند.
🧠 دانش خود را بیازمایید
دانش خود را بیازمایید
خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کردهاید
📝 دستورالعملها
- هر سوال را با دقت بخوانید
- بهترین پاسخ را برای هر سوال انتخاب کنید
- میتوانید آزمون را هر چند بار که میخواهید تکرار کنید
- پیشرفت شما در بالا نمایش داده میشود