آموزش جامع استفاده از Axios در ری اکت (ReactJS)

به نام خدا. با عرض سلام خدمت کاربران گرامی آکادمی راهکارینو، با آموزش کتابخانه Axios و نحوه اجرای درخواست های HTTP توسط Axios در خدمتتان هستیم.
معرفی و نصب axios:
برای ارسال و دریافت درخواست های HTTP یا Http-Requests می توان به روش های مختلف زیر عمل کرد:
- Fetch
- XHR (XMLHttpRequest)
- AJAX
- Axios
اولین روش fetch api می باشد که داخل تمام مرورگرهای مدرن تعریف شده است. به عنوان مثال متد GET به این صورت تعریف می شود:
fetch('examples/example.json') .then((response) => { // Do stuff with the response }) .catch((error) => { console.log('Looks like there was a problem: \n', error); });
و آرگومان دوم fetch شامل request object است:
{ method: 'POST', // *GET, POST, PUT, DELETE, etc. mode: 'cors', // no-cors, *cors, same-origin cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached credentials: 'same-origin', // include, *same-origin, omit headers: { 'Content-Type': 'application/json' }, redirect: 'follow', // manual, *follow, error referrerPolicy: 'no-referrer', // no-referrer, *client body: JSON.stringify(data) // body data type must match "Content-Type" header }
اما از بین روش های فوق، axios بهترین و ساده ترین روش ارسال و دریافت درخواست های HTTP می باشد. کتابخانه Axios در گیتهاب بیش از 88 هزار ستاره از کاربران دریافت کرده است. برای مشاهده صفحه گیتهاب اکسیوس روی این لینک کلیک کنید و برای مشاهده سایت مرجع axios روی این لینک کلیک کنید.
به روش های زیر می توان axios را نصب کرد:
توسط npm:
$ npm install axios
توسط yarn:
$ yarn add axios
توسط CDN:
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> # or <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
اجرای متد GET در axios:
برای دریافت دیتا از سرور متد GET را فراخوانی می کنیم. در این مقاله ساختار هر پست شامل فیلدهای زیر است:
{ "userId": 1, "id": 1, "title": "sunt aut facere occaecati ", "body": "quia et suscipit\nsuscipit ut quas architecto" },
به منظور دریافت لیست پست ها از وب سرویس typicode به شکل زیر عمل می کنیم:
// GET request const getPosts = () => { axios({ method: "get", url: "https://jsonplaceholder.typicode.com/posts", params: { _limit: 5 } }) .then((response) => console.log(response)) .catch((error) => console.log(error)); };
توضیح: مقدار params را به این دلیل تعریف کردیم که می خواستیم تعداد پست های دریافتی از سرور به 5 عدد محدود شود. axios.get یک Promise بر می گرداند که می توان توسط then و catch نتایج برگشتی از درخواست را مدیریت کرد. اگر Request با موفقیت همراه باشد بلاک then اجرا می شود و اگر به هر دلیلی با خطا روبرو شود، به بلاک catch می رود. در بخش method باید نوع متد درخواستی را تعریف کرد (Get, Post, Put, Patch, Delete)
بطور پیش فرض متد axios برابر get است. یعنی اگر نوع متد را تعریف نکنیم، get در نظر گرفته می شود.
دقت کنید که متد get فوق را می توان به صورت زیر نیز تعریف کرد:
axios.get("https://jsonplaceholder.typicode.com/posts", { params: { _limit: 5 }, });
همچنین می توان برای تعریف مقادیر params به شکل زیر عمل کرد:
axios.get("https://jsonplaceholder.typicode.com/posts?_limit=5")
یعنی در خود url مقدار limit_ را تعریف کرد. توجه کنید که در کدهای فوق می توانستیم get. را تعریف نکنیم و به شکل axios(‘api-address’) بنویسیم.
اجرای متد POST در axios:
برای افزودن یک پست جدید به وب سرویس فوق، داریم:
// POST const addPost = () => { axios({ method: "post", url: "https://jsonplaceholder.typicode.com/posts", data: { title: "some title here", body: "some body here", } }) .then((response) => console.log(response)) .catch((error) => console.log(error)); };
مقدار method را باید برابر post قرار دهیم و بجای params مقدار data را با مقادیر دلخواه تعریف می کنیم. نسخه خلاصه تر متد post به شکل زیر خواهد بود:
axios.post("https://jsonplaceholder.typicode.com/posts", { title: "some title here", body: "some body here", });
اجرای متدهای PUT و PATCH در axios:
متدهای put و patch برای آپدیت کردن یکی از رکوردها بکار می رود. فرض کنید می خواهیم پستی که آیدی 1 دارد را آپدیت کنیم.
برای متد put داریم:
// PUT const updatePost = () => { axios({ method: "put", url: "https://jsonplaceholder.typicode.com/posts/1", data: { title: "updated title here", body: "updated body here", }, }) .then((response) => console.log(response)) .catch((error) => console.log(error)); };
توضیح: در متد put آنچه که بعنوان مقادیر ارسالی ثبت می کنیم، کاملا جایگزین مقادیر فعلی رکورد موردنظر می شوند. مثلا فرض کنید می خواهیم عنوان پست اول را آپدیت کنیم. اگر در درخواست put فقط مقدار title را تعریف کنیم، فیلد body مربوط به پست اول از بین می رود. پس باید زمانی از متد put استفاده کنیم که می خواهیم کل فیلدهای یک رکورد را جایگزین کنیم.
برای متد patch داریم:
axios({ method: "patch", url: "https://jsonplaceholder.typicode.com/posts/1", data: { title: "updated title here", }, })
توضیح: برخلاف متد put در متد patch فقط فیلدهایی آپدیت می شوند که در request ارسالی ثبت می کنیم. مثلا در کد فوق، ما فقط فیلد title را بروز رسانی کرده ایم. پس فقط همین فیلد در پست اول جایگزین می شود و سایر فیلدها بدون تغییر باقی می ماند.
اجرای متد Delete در axios:
// DELETE const deletePost = () => { axios .delete("https://jsonplaceholder.typicode.com/posts/1") .then((response) => console.log(response)) .catch((error) => console.log(error)); };
مشاهده می کنید که برای اجرای متد delete مانند متد get عمل می کنیم و فقط کافیست آیدی پست موردنظر را در انتهای آدرس api ارسال کنیم.
اجرای متد all در axios:
فرض کنید می خواهیم بطور همزمان به دو api درخواست ارسال کنیم. بعنوان مثال به دو apiسرویس posts و todos درخواست get بزنیم. اگر بیاییم درخواست ها را بصورت تو در تو و nested تعریف کنیم بهینه نخواهد بود. مثلا اگر در then درخواست اول، درخواست get دوم را صدا بزنیم جالب نیست. زیرا درخواست دوم باید منتظر اجرای درخواست اول بماند. روش بهینه، استفاده از axios.all می باشد. در این روش، تمام درخواست های ارسالی، بطور همزمان و موازی با هم اجرا می شوند.
کد زیر را در نظر بگیرید:
// ALL const multipleRequest = () => { axios .all([ axios.get("https://jsonplaceholder.typicode.com/posts"), axios.get("https://jsonplaceholder.typicode.com/todos"), ]) .then((response) => { console.log(response[0]); console.log(response[1]); }) .catch((error) => { console.log(error[0]); console.log(error[1]); }); };
در کد بالا مشاهده می کنیم که دو api call را بصورت آرایه در axios.all تعریف کرده ایم. در then و catch نیز می توان به شکل آرایه با آنها رفتار کرد (res[0] و error[0] و…)
استفاده از interceptor ها در axios:
وقتی می خواهیم یک تنظیمات مشخصی را روی تمام request ها ثبت کنیم (مثلا بخواهیم header ثابتی را به همراه تمام api call ها ارسال کنیم) می توان از interceptor ها در axios استفاده کرد. دو نوع کلی دارد. می توان روی request و response از interceptor ها استفاده کرد.
اعمال interceptor روی تمام requestها:
در کد زیر، نحوه استفاده از interceptor ها در هنگام ارسال درخواست به سرور بیان شده است:
// Request interceptor for API calls axios.interceptors.request.use( async config => { config.headers = { 'Authorization': `Bearer ${access_token}`, 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded' } return config; }, error => { Promise.reject(error) });
در کد بالا مشاهده می کنید که سه فیلد Authorization , Accept , Content-Type را روی درخواست های ارسالی به سرور تنظیم کرده ایم.
اعمال interceptor روی تمام responseها:
و در کد زیر نحوه استفاده از interceptor ها در هنگام دریافت پاسخ از سرور بیان شده است:
axios.interceptors.response.use( (res) => { return res; }, async (error) => { if (error.response) { if (error.response.status === 401) { // Do something, call refreshToken() request for example; // return a request return axios_instance(config); } if (error.response.status === ANOTHER_STATUS_CODE) { // Do something return Promise.reject(error.response.data); } } return Promise.reject(error); } );
مشاهده می کنید که می توان توسط interceptor ها، خطاهای احتمالی در هنگام ارسال درخواست به سرور را مدیریت کرد. مثلا در هنگام بروز خطای 404 پیغام مناسب به کاربر نمایش داد یا در هنگام خطای 401 یا unauthorized کاربر را به صفحه لاگین هدایت کنیم. بنابراین در صورتی که از interceptor ها بدرستی استفاده کنید دیگر نیازی نیست برای تک تک درخواست ها به سرور خطاهای احتمالی را مدیریت کنید.
استفاده از custom header در axios:
گاهی اوقات ممکن است نیاز باشد برای یک درخواست خاص، از هدر سفارشی یا custom header استفاده کنیم. در این مواقع می توان به شکل زیر هدر دلخواه را تعریف کرد:
// custom header const customHeader = () => { const config = { headers: { "Content-Type": "application/json", Authorization: "sample token", }, }; axios .post( "https://jsonplaceholder.typicode.com/posts", { title: "some text 1", body: "some text 2", }, config ) .then((response) => console.log(response)) .catch((error) => console.log(error)); };
در کد فوق، تنظیمات مربوط به هدر سفارشی را در آبجکت config تعریف کرده ایم و به همراه درخواست post ارسال می کنیم.
مدیریت خطای سفارشی در axios:
گاهی اوقات ممکن است نیاز باشد برای یک درخواست خاص، مدیریت خطای مجزایی داشته باشیم. به کد زیر دقت کنید:
// custom error handling: const errorHandler = () => { axios({ method: "get", url: "https://jsonplaceholder.typicode.com/posts", }) .then((response) => console.log(response)) .catch((error) => { if (error.response.status === 404) history.push("404.jsx"); else if (error.response.status === 401) history.push("login.jsx"); }); };
در کد فوق اعلام کرده ایم که اگر شماره خطای برگشتی از سرور 404 بود کاربر به صفحه 404 هدایت شود. اگر خطای برگشتی از سرور 401 بود، یعنی کاربر احراز هویت نشده است و او را به صفحه لاگین هدایت می کنیم.
تعریف نمونه (instance) از axios:
فرض کنید ابتدای تمام آدرس های وب سرویس در پروژه ما یکسان است و فقط بخش انتهایی آن تغییر می کند. می توانیم با تعریف baseURL به صورت زیر، مقدار ثابت را تعریف کنیم.
// axios instance: const axiosInstance = axios.create({ baseURL: "https://jsonplaceholder.typicode.com", }); axiosInstance .get("/posts") .then((response) => console.log(response)) .catch((error) => console.log(error));
در کد فوق، مقدار https://jsonplaceholder.typicode.com ثابت است، پس می توان بعنوان baseURL تعریف شود. در ادامه اگر از axiosInstance استفاده کنیم، فقط کافیست از / به بعد تعریف شود (مانند posts/).
تعریف timeout در axios:
در axios این قابلیت وجود دارد که مدت زمان انتظار برای اجرای درخواست را تعیین کنیم. یعنی اعلام کنیم که اگر اجرای درخواست ما مثلا بیش از 5 ثانیه طول کشید، دیگر آن را اجرا نکند و پیغام خطا بدهد. نحوه تعریف timeout در درخواست axios به شکل زیر است:
// axios timeout: axios.get('https://jsonplaceholder.typicode.com/posts', { timeout: 5000, timeoutErrorMessage: 'ارسال درخواست بیش از حد طول کشید' }) .then((response) => console.log(response)) .catch((error) => console.log(error));
کنسل کردن request توسط AbortController:
وقتی در useEffect یک درخواستی را توسط axios به سمت سرور ارسال می کنیم، باید مطمئن شویم که وقتی آن کامپوننت unmount می شود، این request نیز کنسل می شود. برای اینکار باید از روش زیر در axios استفاده کرد:
useEffect(() => { const controller = new AbortController(); axios.get('/foo/bar', { signal: controller.signal }).then(function(response) { //... }); return () => { // cancel the request controller.abort(); } }, [input]);
در کد بالا، ابتدا یک instance جدید از آبجکت AbortController می سازیم و در ریکوئست axios مقدار signal را برابر controller.signal قرار می دهیم. سپس در cleanup function یعنی متد return در useEffect (وقتی کامپوننت unmount می شود) دستور controller.abort را صدا می زنیم.
برای مطالعه بیشتر درباره cancellation در axios توسط Abort Controller به سایت مرجع axios مراجعه کنید.
مقاله آموزشی axios در اینجا به پایان می رسد. شما همراهان گرامی آکادمی راهکارینو اگر نکته ای یا سوالی درباره مدیریت درخواست های http توسط axios داشتید می توانید در پایین همین مقاله، کامنت خود را ارسال کنید. تیم پشتیبانی آکادمی راهکارینو در اسرع وقت پاسخگوی سوالات شما خواهد بود.
مطالب زیر را حتما مطالعه کنید
8 دیدگاه
به گفتگوی ما بپیوندید و دیدگاه خود را با ما در میان بگذارید.
درود بر شما
هیچ کجا به این شفافی Axios رو توضیح نداده بودند
راغب شدم تمام مقالات سایت شما رو بخونم
عالییییی
سلام دوست عزیز.
ممنون از نظر لطف شما.
سعی ما بر اینه که تمام مقالات رو به شکل ساده و شفاف ارائه دهیم.
خوشحالیم از همراهی شما 🙂
سلام.عالی بود از زحمتاتتون صمیمانه قدردانی میکنم
درود بر شما. خواهش میکنم. ممنون میشم وب سایت رو با دوستان خود به اشتراک بگذارید.
واقعا عالی بود ساده و قابل فهم
ممنون بابت مقاله تون
سلام پوریا جان. ممنون از نظر مثبت شما.
خوشحالم که مقاله براتون مفید بوده.
ممنون میشم مقاله را با دوستان خود به اشتراک بگذارید
خیلی خوب بود
تشکر از شما
سلام. ممنون از لطف شما