آموزش fetch در جاوا اسکریپت

حالت مطالعه

                                                

 

جاوا اسکریپت می تواند درخواست های شبکه را به سرور ارسال کند و اطلاعات جدید را هر زمان که نیاز باشد بارگیری کند. Fetch یک رابط مدرن است که به شما امکان می دهد؛ درخواست های HTTP را از مرورگرهای وب به سرورها ارسال کنید.

اگر با شیء XMLHttpRequest (XHR) کار کرده اید، Fetch API می تواند تمام وظایف را مانند شیء XHR انجام دهد. علاوه بر این، Fetch API بسیار ساده تر و تمیزتر این کار را انجام می دهد. با آموزش fetch در جاوا اسکریپت، همراه ما باشید.

 

تفاوتFetch باXHR

تفاوت عمده این است که Fetch با promise کار می کند، در صورتی که XHR با callback. توسعه‌دهندگان جاوا اسکریپت پس از معرفی promise از callback دور شده‌ و به سمت promise مهاجرت کردند. متد ()fetch به مرورگرهای وب دستور می دهد تا درخواستی را به URL ارسال کنند.

متد ()fetch مدرن و همه کاره است؛ بنابراین ما آن را انتخاب می کنیم. Fetch توسط مرورگرهای قدیمی پشتیبانی نمی شود، اما در بین مرورگرهای مدرن به خوبی پشتیبانی می شود.

در صورتی که با مبانی پایه ای جاوا اسکریپت آشنایی ندارید می توانید پکیج آموزشی جاوا اسکریپت آکادمی آی تی را مشاهده کنید.

 

promise در درخواست Fetch API

هر متد ()fetch فرآیند درخواست یک منبع را انجام می دهد و یک Promise را برمی گرداند. بحث مفصل در مورد JavaScript Promises خارج از محدوده این آموزش است، اما ما به اندازه کافی برای شما توضیح خواهیم داد که بتوانید با ()fetch کار کنید.

 

Promise

نشان دهنده تکمیل (یا شکست) نهایی یک عملیات و مقدار حاصل از آن است. اگر بخواهیم یک Promise را به چند جمله ساده تر تبدیل کنیم، ممکن است به این صورت باشد:

کاری بکند که وقتی آن «چیز» تمام شد، کار دیگری انجام دهد.

البته، این یک ساده سازی بیش از حد است، اما این مفهوم کم و بیش وجود دارد. شما اساسا چیزی را «وعده» می‌دهید، سپس وقتی آن «چیز» کامل شد، پاسخ می‌دهید. و چون این کار به صورت ناهمزمان انجام می شود، می توانید خطوط دیگر جاوا اسکریپت را در حالی که Promise در حال انجام است اجرا کنید.

در این کد، دو Promise برگردانده شده است، برای هر فراخوانی یک متد ()then:

.then((response) => {
return response.text();
})
.then((data) => {
// do something with 'data'
});

 

این متدهای then() کاری را انجام می دهند که به آن زنجیره زدن گفته می شود، که در Promises امکان پذیر است و کاملاً رایج است. بنابراین برای خلاصه کردن آن مثال: ما یک منبع را «fetch» می کنیم. سپس با «then» پاسخی را برمی‌گردانیم. و پس از خواندن پاسخ، داده‌ها را برمی‌گردانیم.

 

پاسخ Promise در Fetch API

دوباره در کد زیر، به ترکیب آن توجه کنید:

.then((response) => { }

 

داخل متد ()then یک تابع پیکانی است. متد ()then که یکی از ویژگی‌های JavaScript Promises است، آرگومانی را دریافت می‌کند که تابع onFullfilled نامیده می‌شود. این تابع پیکانی که به عنوان آرگومان ارسال می شود؛ شی Response را دربر می گیرد.

هنگامی که Promise انجام شد، شی پاسخ (Response) همان چیزی است که برگردانده می‌شود، و از آنجا که می‌توان آن را به روش‌های مختلفی مدیریت کرد، به تابع منتقل می‌شود، که در ادامه به آن‌ها خواهم پرداخت.

 

خواص و روش های شی پاسخ

تعدادی ویژگی و روش مختلف روی شی پاسخ، پس از دریافت درخواست ()fetch وجود دارد:

Response.ok : این ویژگی یک Boolean برمی گرداند که نشان می دهد آیا درخواست موفقیت آمیز بوده است یا خیر.

Response.status : این ویژگی کد وضعیت پاسخ را برمی گرداند (به عنوان مثال عدد 200، برای یک درخواست موفق).

Response.url : این ویژگی URL درخواست را برمی گرداند. معمولاً هنگام ارسال درخواست، این مورد را دارید.

()Response.clone : یک کلون از شی Response ایجاد می کند.

()Response.text : داده‌های موجود در پاسخ را به صورت متن برمی‌گرداند، که هنگام بازیابی HTML مفید است.

()Response.json: داده‌های موجود در پاسخ را به‌عنوان یک شیء JSON معتبر برمی‌گرداند.

()Response.blob : برای داده هایی که به شکل مرجع فایل هستند؛ (مانند URL تصویر) مفید است.

مطلب پیشنهادی : آموزش dom در جاوا اسکریپت

 

خواندن پاسخ

ما دو روش زنجیره ای ()then را در هنگام برخورد با محتوای درخواستی داریم. اولین ()then جایی است که ما با شی پاسخ سروکار داریم و دومین ()then جایی است که با داده ها پس از خواندن سروکار داریم.
هنگامی که پاسخ دریافت شد و ما انتخاب کردیم که با آن چه کار کنیم (مثلاً آن را به عنوان متن یا به عنوان یک شی JSON بخوانیم)، سپس می توانیم آن را به تابع فراخوانی ()then بعدی، ارسال کنیم. وقتی promise بعدی محقق شد، می‌توانیم داده‌ها را هر طور که می‌خواهیم دستکاری کنیم.

 

چه زمانی درخواست Fetch API رد می شود؟

تمایز مهمی که باید هنگام بررسی درخواست‌های Fetch API موفق و ناموفق داشت؛ در نظر گرفتن خطاهای شبکه در مقابل خطاهای HTTP است.

هنگام درخواست ()fetch اگر مجوز به سندی که fetch را آغاز کرده است داده نشود، در این صورت این درخواست رد شده در نظر گرفته می شود. این درخواست در سطح شبکه رخ می دهد؛ با این حال اگر یک درخواست fetch، محتوایی را درخواست کند که در سرور وجود ندارد، این درخواست همچنان یک درخواست موفقیت‌آمیز در نظر گرفته می‌شود.

 

درخواست Fetch API

برای شروع، اجازه دهید به یک مثال ساده از Fetch API بپردازیم تا بتوانید با ترکیب اصلی آن آشنا شویم:

fetch(url)
.then((response) => {
return response.text();
})
.then((data) => {
// do something with 'data'
});

 

در خط اول کد، از متد ()fetchاستفاده شده است؛ که متدی از شی Window در محیط مرورگر است. بنابراین می توانم به جای آن خط اول را به این صورت بنویسم:

window.fetch(url)

 

متد ()fetch دو آرگومان می گیرد، اما تنها یکی اجباری است: "مکان منبع درخواستی". در مثال بالا، مکان آن منبع را در متغیری به نام url تعریف کرده‌ایم.

همچنین بخوانید : آموزش function در جاواسکریپت

 

رسیدگی به خطا در fetch

Promise به خطاهای HTTP توجه نمی کند (به عنوان مثال: خطای 404 و 500)؛ فقط در صورت مواجه شدن با خطای شبکه، این خطاها را لحاظ می کند. بنابراین ما باید از ()then برای بررسی خطاهای HTTP با ویژگی های answer.ok و یا answer.status استفاده کنیم.

fetch('/example.com/data')
.then(function(response) {
// if (response.status !== 200)
if (!response.ok) {
console.log('Error with Status Code: ' + response.status);
return;
}
response.json().then(function(data) {
console.log(data);
});
})
.catch(function(err) {
console.log('Error: ' + err);
});

 

ترکیب fetch try catch

اگر بخواهیم از async-await استفاده کنیم، کافی است fetch را با try/catch مانند مثال زیر استفاده کنیم:

 

async function getData() {
try {
const response = await fetch('/example.com/data');
if (!response.ok) {
const message = 'Error with Status Code: ' + response.status;
throw new Error(message);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.log('Error: ' + err);
}
}

 

fetch با param

می توانید از شی URL با URLSearchParams برای تنظیم پارامترهای رشته search استفاده کنید مانند مثال زیر:

let url = new URL('/example.com/data');
const params = { title: 'web'};
url.search = new URLSearchParams(params);
try {
const response = await fetch(url);
if (!response.ok) {
const message = 'Error with Status Code: ' + response.status;
throw new Error(message);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.log('Error: ' + err);
}


و این معادل است با:

const response = await fetch('/example.com/data?title=web');

 

fetch با headers

برای ارسال درخواست Fetch با Headers، یک شی با ویژگی متد و هدر ارسال می کنیم:

const options = {
method: 'get',
headers: {
"Content-Type": "application/json",
"x-access-token": "token-value",
}
};
try {
const response = await fetch('/example.com/data', options);
if (!response.ok) {
const message = 'Error with Status Code: ' + response.status;
throw new Error(message);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.log('Error: ' + err);
}

 

متد post در fetch

متد post به شکل های زیر انجام می شود:

•    Fetch POST Form data
•    Fetch POST JSON
•    Fetch POST file

 

Fetch POST Form data

بیایید یک درخواست POST با Formdata در بدنه درخواست ایجاد کنیم.

let formData = new FormData();
// formData.append('title', 'example Tutorial');
// formData.append('description', 'Tut Desc');
formData.append('file', file);
try {
const response = await fetch('/example.com/data', {
method: "post",
body: formData
});
if (!response.ok) {
const message = 'Error with Status Code: ' + response.status;
throw new Error(message);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.log('Error: ' + err);
}

اگر از application استفاده می‌کنید، کلیدها و مقادیر به صورت کلید مقدار کدگذاری می‌شوند.

 

Fetch POST JSON

بیایید یک درخواست POST با JSON ایجاد کنیم.  ما از ()JSON().stringify روی شی، قبل از ارسال آن در بدنه استفاده می کنیم و application/json را برای سربرگ Content-Type تنظیم می کنیم.

const postData = {
title: title,
description: description,
};
try {
const response = await fetch('/example.com/data', {
method: "post",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(postData)
});
if (!response.ok) {
const message = 'Error with Status Code: ' + response.status;
throw new Error(message);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.log('Error: ' + err);
}

 

Fetch POST file

کار با فایل مشابه مورد قبلی با استفاده از داده های فرم است:

let formData = new FormData();
// formData.append('title', 'Example Tutorial');
// formData.append('description', 'Tut Desc');
formData.append('file', file);
try {
const response = await fetch('/example.com/data', {
method: "post",
body: formData
});
if (!response.ok) {
const message = 'Error with Status Code: ' + response.status;
throw new Error(message);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.log('Error: ' + err);
}

ما نیازی به تنظیم Content-Type header با داده های چندبخشی نداریم. مرورگر به طور خودکار نوع محتوای مناسب، از جمله فرم را انتخاب می کند.

 

ارسال تصویر با fetch

همچنین می‌توانیم داده‌های باینری را با fetch و با استفاده از اشیاء Blob یا BufferSource ارسال کنیم. در این مثال، یک <canvas> وجود دارد که می‌توانیم با حرکت ماوس روی آن نقاشی کنیم. با کلیک بر روی دکمه "submit" تصویر به سرور ارسال می شود:

<body style="margin:0">
<canvas id="canvasElem" width="100" height="80" style="border:1px solid"></canvas>
<input type="button" value="Submit" onclick="submit()">
<script>
    canvasElem.onmousemove = function(e) {
        let ctx = canvasElem.getContext('2d');
        ctx.lineTo(e.clientX, e.clientY);
        ctx.stroke();
    };
    async function submit() {
        let blob = await new Promise(resolve => canvasElem.toBlob(resolve, 'image/png'));
        let response = await fetch('/article/fetch/post/image', {
            method: 'POST',
            body: blob
        });
        // the server responds with confirmation and the image size
        let result = await response.json();
        alert(result.message);
    }
</script>
</body>

 

تابع ()submit را می توان بدون async/await بازنویسی کرد:

function submit() {
canvasElem.toBlob(function(blob) {
fetch('/article/fetch/post/image', {
method: 'POST',
body: blob
})
.then(response => response.json())
.then(result => alert(JSON.stringify(result, null, 2)))
}, 'image/png');
}

 

Javascript Fetch PUT

اکنون نمونه Fetch PUT را با داده های JSON تولید می کنیم. شبیه درخواست Fetch POST است:

const postData = {
title: title,
description: description,
};
try {
const response = await fetch('/example.com/data', {
method: "put",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(postData)
});
if (!response.ok) {
const message = 'Error with Status Code: ' + response.status;
throw new Error(message);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.log('Error: ' + err);
}

 

Fetch DELETE

حذف کردن در این متد به شکل زیر می باشد:

try {
const response = await fetch('/example.com/data/42', {
method: "delete"
});
if (!response.ok) {
const message = 'Error with Status Code: ' + response.status;
throw new Error(message);
}
const data = await response.json();
console.log(data);
} catch (error) {
console.log('Error: ' + err);
}

نتیجه

با استفاده از آموزش fetch در جاوا اسکریپت، شما راه‌های زیادی برای ایجاد درخواست GET/POST/PUT/DELETE با استفاده از Fetch API (با هدرها، پارامترها، بدنه، داده‌های فرم و…) آموختید. اکنون شما همچنین می دانید که چگونه خطا را در درخواست Fetch مدیریت کنید یا از async/wait با دستور try/catch استفاده کنید.

امیدوارم مثال‌های این پست برای شما مفید بوده باشد و درک کلی مناسبی از نحوه عملکرد Fetch در جاوا اسکریپت به شما داده باشد.
 

دپارتمان: آموزش طراحی سایت
2 0 نظر

سبد خرید

سبد خرید شما خالی است.