ایجاد درخواست HTTP در جاوا اسکریپت
درخواست HTTP در جاوا اسکریپت
در مورد توسعه برنامههای مدرن، اعم از وب، موبایل یا سایر موارد، تقریباً همیشه نیاز به تعامل با سرویسهای وب از راه دور، معمولاً از طریق HTTP وجود دارد. هنگام کار با چارچوبهایی مانند Angular ، Vue و React ، عملکردهای مختلفی برای درخواست HTTP وجود دارد، اما اگر از JavaScript استفاده میکنید یا ترجیح میدهید از موارد ساخته شده و آمده استفاده نکنید، چه میکنید؟ در این آموزش میخواهیم چند گزینه برای ایجاد درخواست HTTP در JavaScript را بررسی کنیم. به طور خاص ما با استفاده از واکشی جاوا اسکریپت (javascript) مدرن و همچنین استفاده از یک بسته شخص ثالث به نام Axios، به درخواست کلاسیک XHR و درخواست HTTP در جاوا اسکریپت خواهیم پرداخت.
نحوه انتخاب روش ایجاد درخواست HTTP در جاوا اسکریپت
هنگام تصمیمگیری در مورد چگونگی ایجاد درخواستهای HTTP در JavaScript، به عملکرد آن باید دقت کنیم و بر اساس عملکرد موردنظر تصمیم به انتخاب یکی از راهحلهای موجود بپردازیم. هرکدام از مواردی که ذکر میشود نقاط قوت خود را دارند و از طرفی دارای ضعفهایی هم هستند.
در آغاز، برخی روشها برای برداشتن دادهها از سرور بدون بازخوانی صفحه وجود داشته است، اما آنها اغلب به تکنیکهای پیچیده متکی بودند. مایکروسافت XMLHttpRequest را برای یک مرورگر جایگزین سرویسگیرنده ایمیل Outlook خود کرد. XMLHttpRequest در سال ۲۰۰۶ به یک استاندارد وب تبدیل شد.
Fetch API در سال ۲۰۱۵ با ES6 معرفی شد. رابطهای عمومی درخواست و پاسخ سازگاری را ارائه میدهند درحالیکه وعدهها (promises) زنجیره زنی آسانتری را ایجاد میکنند و بدون بازگشت تماس را در حالت همگامسازی قرار میدهند. واکشی تمیز، زیبا و ساده است، اما گزینههای خوب دیگری نیز وجود دارد که به طور خلاصه در این مقاله بررسی خواهیم کرد و در ادامه به طور مفصل در خصوص چند مورد خدمت شما توضیحاتی را ارائه خواهیم داد. روشهای ایجاد درخواست در جاوا اسکریپ شامل موارد زیر است:
- XMLHttpRequest
- ajax
- Qwest
- SuperAgent
- مشتری Http
- Axios
- Fetch
کد زیر یک مثال اساسی HTTP GET و POST را با استفاده از گزینههای مختلف نشان میدهد.
XMLHttpRequest
از XMLHttpRequest میتوان برای درخواست داده از سرور وب استفاده کرد. این قدیمیترین روش این مقایسه است و اگرچه گزینههای دیگر از آن پیشی میگیرند، اما همچنان سازگار و کارا است.
GET
var req = new XMLHttpRequest();//The onreadystatechange property
//specifies a function to be
//executed every time the status
//of the XMLHttpRequest changes
req.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//The responseText property
//returns a text string
console.log(xhttp.responseText)
//Do some stuff
}
};req.open("GET", "http://dataserver/users", true);
req.send();
POST
var formData = new FormData();
formData.append("name", "Milad");
var req = new XMLHttpRequest();
req.open("POST", "http://dataserver/update");
req.send(formData);
JQuery.ajax
این کتابخانه تا چندی پیش برای ایجاد درخواستهای ناهمزمان HTTP به طور گسترده مورداستفاده قرار گرفت.
همه روشهای Ajax jQuery یک مجموعه بزرگ از شی XMLHTTPRequest را برمیگرداند
GET
$.ajax({
url: 'http://dataserver/data.json'
}).done(function(data) {
// ...do some stuff whith data
}).fail(function() {
// Handle error
});
POST
$.ajax({
type: "POST",
url: 'http://dataserver/update',
data: data,
success: successCallBack,
error: errorCallBack,
dataType: dataType
});
Qwest
Qwest یک کتابخانه آژاکس ساده است که بر اساس وعدهها یا (Promises) ارائه شده است و از دادههای منحصربهفرد XmlHttpRequest2 مانند ArrayBuffer ، Blob و FormData پشتیبانی میکند.
GET
qwest.get('http://dataserver/data.json')
.then(function(xhr, response) {
// ...do some stuff whith data
});
POST
qwest.post('http://dataserver/update', {
firstname: 'Milad',
age: 30
})
.then(function(xhr, response) {
// Make some useful actions
})
.catch(function(e, xhr, response) {
// Process the error
});
SuperAgent
SuperAgent ajax API است که برای انعطافپذیری، خوانایی و با منحنی یادگیری کم ایجاد شده است. همچنین با Node.js کار میکند.
GET
request('GET', 'http://dataserver/data.json').then(
success, failure);
متد . query () اشیا را میپذیرد که اگر با روش GET استفاده شود، یکرشته query ایجاد میکند. موارد زیر مسیر / dataserver / search؟ name = Manny & lastName = Peck & order = desc را تولید میکند.
request
.get('/dataserver/search')
.query({ name: 'Templeton' })
.query({ lastname: 'Peck' })
.query({ order: 'desc' })
.then(res => {console.dir(res)}
});
POST
request
.post('http://dataserver/update')
.send({ name: 'Milad' })
.set('Accept', 'application/json')
.then(res => {
console.log('result' + JSON.stringify(res.body));
});
GET
//using ES6 modules
import { createFetch, base, accept, parse } from 'http-client'const fetch = createFetch(
base('http://dataserver/data.json'),
accept('application/json'),
parse('json')
)fetch('http://dataserver/data.json').then(response => {
console.log(response.jsonData)
})
POST
//using ES6 modules
import { createFetch, method, params } from 'http-client'const fetch = createFetch(
params({ name: '' }),
base('http://dataserver/update')
)
Axios
کتابخانه HTTP مبتنی بر وعده (promise) برای انجام درخواستهای HTTP در مرورگر و Nodejs
GET
axios({
url: 'http://dataserver/data.json',
method: 'get'
})
POST
axios.post('http://dataserver/update', {
name: ''
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
FETCH
Fetch یک API مرورگر بومی است تا درخواستی را جایگزین XMLHttpRequest کند. Fetch اجازه میدهد تا درخواستهای شبکه را آسانتر از XMLHttpRequest اعمال کنید. Fetch API از promises برای جلوگیری از اختلال پاسخگویی XMLHttpRequest استفاده میکند.
GET
//With ES6 fetch
fetch('http://dataserver/data.json')
.then(data => {
// ...do some stuff whith data
}).catch(error => {
// Handle error
});
POST
fetch('http://dataserver/update', {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify({name: 'Milad'})
}).then(res=>res.json())
.then(res => console.log(res));//OR with ES2017 for example(async () => {
const response = await fetch(‘http://dataserver/update’, {
method: ‘POST’,
headers: {
‘Accept’: ‘application/json’,
‘Content-Type’: ‘application/json’
},
body: JSON.stringify({name:’’})
});const result = await response.json();console.log(result);
})();
اما بپردازیم به مهمترین بخش این مقاله که به طور مفصل روش درخواست جا و اسکریپت را برای چندین روش که در بالا اشاره شد توضیح میدهیم:
درخواست جاوا اسکریپت XHR
اگر مدت زیادی است که با JavaScript کار میکنید، احتمالاً شنیدهاید که XMLHttpRequest (XHR) یکی از روشهای درخواست در جاوا اسکریپت است. روش XHR کاملاً قدرتمند است زیرا شما میتوانید از یک منبع از راه دور داده درخواست کنید، از یک منبع از راه دور داده دریافت کنید یا به یک منبع از راه دور داده ارسال کنید. تمام آنچه که ذکر شد ممکن است شبیه به هم باشند، اما آنها بخشهای مختلف فرایند HTTP هستند.
بنابراین بیایید نگاهی به یکی از این درخواستها بیندازیم:
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if(xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
};
xhr.open("GET", "http://httpbin.org/get", true);
xhr.send();
در مثال بالا ما در حال ایجاد یک شی جدید XMLHttpRequest هستیم. اگر بخواهیم کاری را با نتیجه درخواست انجام دهیم، باید با مبحث تغییر listener آشنا شویم. در مثال مذکور، ابتدا باید بررسی میکنیم که درخواست کامل باشد، ازاینرو اگر مقدار readyState برابر ۴ باشد کد ما با موفقیت کارکرده و کد درست است.
چهار مقدار مختلف حالت readyState را میتوان در مستندات MDN برای درخواستهای XHR یافت پس زحمت بکشید قبل از هر چیز با این چهار مقدار آشنا شوید. اگر این مستندات را بررسی کنید تعداد کمی از کدهای وضعیتی وجود دارد که میتوانند از سرور برگردانده شوند. در یک سناریو واقعبینانه، شما احتمالاً میخواهید همه امکانات برای بهترین تجربه کاربر را در خود جای دهید.
برای این مثال، پاسخ درخواست فقط در قسمت لاگ قابلمشاهده خواهد بود. هنگام بازکردن درخواست، URL مشخص میشود.
حالا بیایید درخواست XHR را کمی پیچیده کنیم. بیایید موارد زیر را انجام دهیم:
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if(xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
};
xhr.open("POST", "http://httpbin.org/post?key=123", true);
xhr.send(JSON.stringify({ "firstname": "", "lastname": "Vahidi" }));
در کد بالا، ما اکنون یک درخواست POST با پارامترهای کوئری (query parameters) و یک بدنه درخواست (body request) ایجاد کردهایم. توجه داشته باشید که ما باید پارامترهای درخواست را از طریق url رمزگذاری کنیم و همچنین متن درخواست را بهصورت سریالایز شده تنظیم کنیم.
XMLHttpRequest قدرتمند است، اما به نظر من مشکل بیش از ارزش آن است. این امر ما را به رویکردهای مدرنتری نسبت به درخواستهای HTTP با JavaScript هدایت میکند.
ایجاد درخواست از طریق JavaScript Fetch Request
عملکرد واکشی اطلاعات درخواست شما را میگیرد و نتیجه معروف به promise را پس میدهد.
بیایید نگاهی بیندازیم به درخواست XHR با این تفاوت که در این قسمت از واکشی اطلاعات استفاده میکنیم.
fetch("http://httpbin.org/get")
.then(response => response.json())
.then(response => {
console.log(response);
}, error => {
console.error(error);
});
بهجای نگرانی در مورد ایجاد listener یا نگرانی در مورد کد وضعیت پاسخ، میتوانیم بررسی کنیم که آیا promise موفقیتآمیز بوده یا رد شده است. عملکرد واکشی یک promise با دادههای خام را میدهد که باید به JSON، متن یا موارد دیگر تبدیل شود. به همین دلیل است که از زنجیره promise استفاده میشود. نتیجه نهایی این کد خاص بهصورت JSON برگردانده میشود، بنابراین آن را به همین صورتی که هست تبدیل میکنیم قبل از اینکه آن را در زنجیر کردن به یک حلقه جدید در زنجیره promise درگیر کنیم.
اگرچه واکشی برای بسیاری از موقعیتها بسیار قدرتمند است، اما گاهی اوقات میتواند نیاز به، بهکارگیری ظرافت خاصی نداشته باشد. اجازه دهید برخی موارد را در درخواست خود تغییر دهیم:
fetch("http://httpbin.org/post?key=123", {
"method": "POST",
"body": JSON.stringify({
"firstname": "",
"lastname": "Vahidi"
})
})
.then(response => response.json())
.then(response => {
console.log(response);
});
در درخواست فوق، ما در حال تغییر از GET به POST هستیم و در حال تزریق request body و همچنین query parameters هستیم. توجه داشته باشید که query parameters مستقیماً با URL در یک خط قرار دارند و equest body یک serialized JSON object است.
برای بهبود کارها، میتوانیم به سمت کتابخانه شخص ثالثی برویم که در برنامههای JavaScript ما مورداستفاده قرار میگیرد.
درخواستهای HTTP با Axios JavaScript Library
یکی از کتابخانههای مهم برای ایجاد درخواست HTTP، کتابخانه axios است.
اگر از NPM استفاده میکنید، میتوانید دستور زیر را اجرا کنید:
npm install axios –save
اگر از Node.js یا یک چارچوب مدرن حاوی Webpack یا موارد مشابه دیگر استفاده میکنید، دستور فوق عالی کار خواهد کرد، اما هنگام ساخت یک برنامه کاربردی مبتنی بر مرورگر با جاوا اسکریپت کمک چندانی نمیکند. در عوض، میتوانید کتابخانه را با تگ زیر وارد کنید:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
ازآنجاکه این یک مثال یک مبحث پایهای و بنیادی در JavaScript است، استفاده از تگscript خوب است، توجه داشته باشید که اگر از رویکرد NPM استفاده میکنید، فراموش نکنید که کتابخانه را در فایل JavaScript وارد کنید.
با استفاده از کد زیر، میتوانید از axios استفاده کنید:
axios({
"method": "GET",
"url": "http://httpbin.org/get"
}).then(response => {
console.log(response.data);
});
کد فوق نسخه اصلی استفاده از تابع واکشی یا XMLHttpRequest است. مانند عملکرد واکشی، خروجی رویکرد axios یک promise است.
موارد زیر را به عنوان مثال در نظر بگیرید:
axios({
"method": "POST",
"url": "http://httpbin.org/post",
"params": {
"key": "123"
},
"data": {
"firstname": "",
"lastname": "Vahidi"
}
}).then(response => {
console.log(response.data);
});
توجه داشته باشید که ما این بار روش درخواست را به درخواست POST تغییر دادهایم. در این قسمت تصمیم گرفتیم که پارامترهای جستجو را در URL بخواهیم که از طریق شی params و یک بدنه درخواست که به شی داده اضافه شده است، اضافه شوند. البته نیازی نبود که این پارامترها را با استفاده از url رمزگذاری کنیم یا متن درخواست را سریالسازی کنیم بهویژه هنگامیکه تعداد درخواستهای زیادی دارید یا پارامترهای جستجوی زیادی دارید. حتی میتوانید اطلاعات هدر را نیز در این بخش اضافه کنید.
نتیجه گیری
چند گزینه برای ایجاد درخواستهای HTTP در برنامههای JavaScript را مشاهده کردید. رویکردهای ذکر شده، در برخی شرایط، باید فراتر از برنامههای وب باشد. این بدان معنی است که شما باید بتوانید از رویکردهای ذکر شده در برنامههای مبتنی بر مرورگر، برنامههای backend، برنامههای تلفن همراه کراس پلتفرم و موارد دیگر استفاده کنید.
بهطورکلی بهتر است در مواقعی که درخواست پیچیدهتری موردنیاز باشد، از axios به کتابخانه شخص ثالث استفاده کنیم.