You may not know how to use Axios

  • In the daily development of the front-end, in addition to purely static display pages, it is necessary to make some interface requests, from XMLHttpRequest, to jQuery ajax, to later Fetch and Axios.

Why choose Axios

  • Create XMLHttpRequests from the browser
  • Create http request from node.js
  • Support Promise API
  • Intercept requests and responses
  • Transform request data and response data
  • Cancel request
  • Automatically convert JSON data
  • Client supports XSRF defense

Why not use Fetch

  • Fetchch only reports errors for network requests, and it is regarded as a successful request for 400500, which needs to be encapsulated for processing
  • The fetch does not have cookie s by default, so you need to add configuration items (Axios also needs to)
  • fetch does not support abort and timeout control. Timeout control implemented with setTimeout and Promise.reject does not prevent the request process from running in the background
  • fetch has no way to monitor the progress of the request natively

Basic configuration

install

# npm
$ npm install axios
# yarn
$ yarn add axios
# cdn
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
Copy code

Direct use

1. Use. To execute a request method, [method name] includes request, head, get, put, delete, post and patch.

axios[method name](url[, data[, config]])
Copy code

2. Called using the way the config object was passed in

axios([config])
.then(response => response)
.catch(error => error)

// Configuration options for config options. Only URLs are required. If no method is specified, the request will use the get method by default.
{
  // `URL 'is the server URL used for the request
  url: '/user',

  // `Method 'is the method used to create a request
  method: 'get', // get by default

  // `baseURL will be automatically added before 'url', unless' url 'is an absolute url.
  // It can easily pass the relative URL for axios instance by setting a 'baseURL'
  baseURL: 'https://some-domain.com/api/',
  
  // `Headers' are the custom request headers to be sent
  headers: {'X-Requested-With': 'XMLHttpRequest'},

  // `params' is the URL parameter to be sent with the request
  // Must be a plain object or URLSearchParams object
  params: {
    ID: 12345
  },
  ...,
  // `Cancel token ` specifies the cancel token used to cancel the request
  // (see the Cancellation section later to learn more.)
  cancelToken: new CancelToken(function (cancel) {
  })
Copy code

3. Concurrent processing

axios.all(iterable)
axios.spread(callback)

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // Both requests completed
  }));
Copy code

Create instance use

  • Create a request instance through axios.create to receive a config object;
import axios from axios;
var instance = axios.create([config]);
Copy code

Default config configuration

1. Configure request timeout

# Use defaults
axios.defaults.timeout = 30000 // Time in milliseconds
# Use instance to pass in config
var instance = axios.create({
    timeout: 30000 
});
Copy code

2. Configure requests to carry cookie s

# Use defaults
axios.defaults.withCredentials = true // trueFor auto carry
# Use instance to pass in config
var instance = axios.create({
    withCredentials: true
});
Copy code

3. Configure baseURL

  • The base url will automatically precede the url unless it is an absolute url.
# Use defaults
axios.defaults.baseURL = 'https://github.com/detanx'
# Use instance to pass in config
var instance = axios.create({
    baseURL: 'https://github.com/detanx'
});
Copy code

4. Configure headers

  • For example, set token
# Use defaults
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
# Use instance to pass in config
var instance = axios.create({
    headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': AUTH_TOKEN
});
Copy code

5. Cancel request cancelToken

  • (1) Use the CancelToken.source factory method to create a cancelToken.
const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get(url, {
  cancelToken: source.token
}).catch(thrown => thrown);

// Cancel request (message parameter is optional)
source.cancel('cancel.');
Copy code
  • (2) The cancelToken is created by passing an executor function to the constructor of the cancelToken.
const CancelToken = axios.CancelToken;
let cancel;

axios.get(url, {
  cancelToken: new CancelToken(function executor(c) {
    // The executor function takes a cancel function as an argument
    cancel = c;
  })
})

// Cancel request (message parameter is optional)
cancel('cancel.');
Copy code

6,More

Interceptor configuration and error handling

  • Intercept requests or responses before they are processed by then or catch.

Request interception

  • You can add it directly to the Axios in import. It is generally recommended to create a new Axios instance and mount the default value and interceptor to the instance.
const NotCancleUrl = ['/stockserver/user/login-user']; // Do not cancel the url list of duplicate requests
const pendingRequestArray = []; // Declare an array to store the cancellation function and request ID of each request
const { CancelToken } = axios;
const removePending = config => {
  for (const index in pendingRequestArray) {
    const key = `${config.url}&${config.method}`;
    if (pendingRequestArray[index].key === key && !NotCancleUrl.includes(config.url)) {
      // Execute function body when current request exists in array
      pendingRequestArray[index].cancel(); // Perform cancel operation
      pendingRequestArray.splice(index, 1); // Remove this record from the array
    }
  }
};
// Add request interceptor
axios.interceptors.request.use( config => {
    // For example, add cancel duplicate request
    removePending(config); // Perform a cancel operation before sending a request
    config.cancelToken = new CancelToken(c => {
      // The request ID here is a string concatenated by the request address request method. You can choose some other methods
      pendingRequestArray.push({ key: `${config.url}&${config.method}`, cancel: c });
    });
    return config;
  }, function (error) {
    // Processing request error
    return Promise.reject(error);
  });
Copy code

Response interception

1. In the above request interception, repeated requests are intercepted. If the request is successful, we should remove the corresponding request from the array of pending request array cache requests after the request is successful.

// Add response interceptor
axios.interceptors.response.use(
  // Process response data
  response => {
    removePending(response.config); // Remove from pendingRequestArray after the request is successful
    return response;
  },
  // Processing response error
  error => {
    return Promise.reject(error);
  }
);
Copy code

2. Do the same processing for the corresponding request timeout, 401, 403 states (of course, you can also do some other processing according to the actual application in your project).

axios.interceptors.response.use(
  response => response,
  error => {
    // Service request timeout
    if (error === undefined || error.code === 'ECONNABORTED') {
      message.warning('Service request timeout');
      return Promise.reject(error);
    }
    const {
      response: { status }
    } = error;
    const { response } = error;
    const info = response.data;
    // 401 not logged in
    if (status === 401) {
      // Not logged in to redirect login page
      ...
    }
    // 403 access denied
    if (status === 403) {
      ...
    }
    return Promise.reject(error);
  }
)
Copy code

error handling

1. Processing in the requested catch method

axios.get(url)
  .catch(function (error) {
    if (error.response) {
      const { data, status, headers } = error.response;
      // Request issued, but server response status code is not in 2xx range
      console.log(data, status, headers);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
    console.log(error.config);
  });
Copy code

2. Use the validateStatus configuration option to define the error range for a custom HTTP status code.

axios.get(url), {
  validateStatus: function (status) {
    return status < 500; // Status code will reject when it is greater than or equal to 500
  }
})
Copy code

Application in project

  • The default settings and interceptors have been mentioned before, and only the request method instance encapsulation is mentioned below.

General use package

// Request method
export const AXIOS_METHOD_TYPET = {
  GET: 'GET',
  POST: 'POST',
  PUT: 'PUT',
  DELETE: 'DELETE',
  PATCH: 'PATCH'
};
/** Method description
 * @method request
 * @param api Request relative address
 * @param method Request method, default get
 * @param params Request parameter is null by default
 * @param config Request configuration is empty by default
 * @return function Return to axios instance
*/
const request = (api, method = AXIOS_METHOD_TYPET.GET, params = {}, config = {}) => {
    method = method.toLocaleUpperCase();
    // get requests are placed in params, and other requests are placed in body
    const data = method === 'GET' ? 'params' : 'data';
    // This part can also be set in defaults
    let headers = {
        'X-Requested-With': 'XMLHttpRequest',
        'Content-Type': 'application/json'
    };
    if (config.headers) {
        headers = {
          ...headers,
          ...config.headers
        };
    }
    return axios({
        url: api,
        method,
        [data]: params,
        headers
    });
};
export default request;
Copy code

How to use

// index.js
import request from 'request';
request('/user/login', post, {
    username: 'detanx',
    password: '123456'
}).then(response => console.log(response))
.catch(error => console.log(error))
Copy code

hooks call encapsulation

// useRequest.js
import { useState, useEffect } from 'react';
// Instance is an axios instance exposed in myAxios with default methods and interceptors added
import { instance, AXIOS_METHOD_TYPET } from './myAxios';

/** Method description
 * @method useRequest
 * @return [
        responseData, // Request successful return
        errorData, // Request failed return
        loading, // Whether the request is completed
        setRequestParams // Parameter change re request
    ] 
*/
const useRequest = (url, method = AXIOS_METHOD_TYPET.GET, params = {}, config = {}) => {
    method = method.toLocaleUpperCase();
    const data = method === 'GET' ? 'params' : 'data';
    const [responseData, setResponseData] = useState({});
    const [errorData, setErrorData] = useState({});
    const [loading, setLoading] = useState(true);
    const [requestParams, setRequestParams] = useState(params);
    let headers = {
        'X-Requested-With': 'XMLHttpRequest',
        'Content-Type': 'application/json'
    };
    if (config.headers) {
        headers = {
            ...headers,
            ...config.headers
        };
    }
    useEffect(() => {
        instance({
            url,
            method,
            [data]: requestParams,
            headers
        })
            .then(({ data }) => {
                setLoading(false);
                setResponseData(data);
            })
            .catch(err => {
                setLoading(false);
                setErrorData(err);
            });
    }, [requestParams]);
    return [
        responseData,
        errorData,
        loading,
        setRequestParams
    ];
};
export default useRequest;
Copy code

How to use

// index.js
import useRequest from 'useRequest';
expoert default () => {
    const [
        responseData,
        errorData,
        loading,
        setRequestParams
    ] = useRequest('/api/user', 'get')
    const clickHandle = () => {
        setRequestParams({name: 'detanx'})
    }
    return (<>
        <button onClick={clickHandle}>New parameter request</button>
    </>)
}
Copy code

hooks package

  • There is a problem with the above encapsulation, that is, every time useRequest is used, a request will be directly initiated. In fact, some pages do not need a request to enter, such as the pure login page, which only needs to initiate a request when the login information is submitted, so the encapsulation above is optimized. If the contract params is false, the request will not be initiated.
// Modify the default value of params tofalseAnd do not send requests by default
const useRequest = (url, method = AXIOS_METHOD_TYPET.GET, params = false, config = {}) => {
    ...
    useEffect(() => {
        // The agreement 'params' is`false`Do not request
+       if (requestParams === false) return;        
        instance()
    }, [requestParams]);
    ...
};

Copy code

Epilogue

  • Most of the requirements in daily development are enough. If you have other requirements in your project, please leave a message.

Tags: axios JSON npm github

Posted on Sun, 03 May 2020 13:16:58 -0400 by Stryves