14

There are dreams and dry goods. search 16119b1910110d [Great Move to the World] still doing dishes in the early morning.

This article GitHub https://github.com/qq449245884/xiaozhi has been included, the first-line factory interview complete test sites, materials and my series of articles.

This article is the content shared by our team every week, and the content is organized and shared by the instructor. Eaxios is a library used by our front-end team and packaged by the instructor. Because other friends are curious about it, the content of this article is shared.

The text begins~~

Eaxios

Eaxios is axios , which simplifies the response content of the server and the handling of various abnormal situations while keeping the API basically consistent with axios.

Development background

image.png

As shown in the figure above, it is the possible output result of an Ajax request. At the front end, we need to give users different prompts based on the output result.

  • Request cancelled: ignored
  • Network abnormal: prompt to check whether it is connected to the network
  • Request timeout: prompts that the network is slow, please switch the network
  • Server exception: indicates that there is a problem with the system
  • Response analysis failed: Same as above, and error log report can be performed
  • Request failed: This situation is usually a business exception, the front end needs to deal with the error code accordingly, the simplest is the message reminder
  • Request successful: update the interface after the front end gets the data

However, the existing Axios library does not provide a better package for abnormal results. Axios Promise catch contains various types of errors, and it does not provide an error code to identify the cause of the request failure. And many server-side interfaces will return their own error codes, so business exceptions need to be handled in Axios Promise then.

In addition, Axios itself has some problems and limitations as described below.

  • If the Axios responseType is set to json, the non-JSON format response content returned by the server will not be parsed, and response.data will be null

    For errors such as 500, the response content will be lost, so don't configure responseType as json, it is easy for users to catch this pit.

    ps: Although the official Axios document states that the responseType is json, in fact the responseType of the underlying call XMLHttpRequest does not pass a value, it should be to avoid this problem.

  • transformResponse regardless of the HTTP response status and responseType.

    ps: It should be to circumvent the previous problem. By default, a response processing function is provided for JSON parsing, but this will affect performance (when the response content value is too large, such as 500, the page will freeze). Although transformResponse can convert response, the actual received parameter is response.data, so it is impossible to determine the specific situation to decide whether to parse JSON.

  • Axios then and catch are determined based on validateStatus , which is more troublesome for users to process.

    Ideally, users expect then to return valid data, and catch to return various error conditions: request cancelled, network exception, network timeout, server exception, server data format error, business exception.

  • Axios does not process content-type as application/x-www-form-urlencoded default, which is not convenient enough to use

Optimization:

  • If you set Axios responseType to json, don’t pass it to XMLHttpRequest to avoid loss of response content in non-JSON format
  • Axios judges whether JSON needs to be parsed according to the content-type of the response header to avoid performance problems

    The request interceptor realizes that the transformResponse configuration is not passed to Axios, and the configuration is backed up to other fields, and then the response object response is passed to the transformResponse processing in the response interceptor. The response interceptor judges whether to perform JSON conversion based on the status code, response header, and response content provided by the response.

  • Cancel the configuration option of Axios validateStatus. By default, all status codes greater than 0 are correct status codes, and then perform data analysis in the Axios interceptor then (non-200 may also be JSON, so you need to reuse the 200 JSON parsing code), And throw intuitive error objects according to abnormal conditions
  • Built-in request body that handles the form type by default

Instructions

eaxios mainly made some optimizations to the response processing, except for the following parts, the api of eaxios is consistent with that of axios:

  • The parameter transfer and processing timing of transformResponse requested by eaxios has changed

    After axios responds to the content on the server side, it will call transformResponse to convert the response. After eaxios responds, it will automatically parse the JSON according to the response header and responseType, and then pass the parsed data and response to transformResponse. The data returned by transformResponse will eventually be Promise resovle To external callers.

    Assuming that the data structure returned by the server is { code: 0, message: 'success', data: {} } , a code of 0 indicates a correct response, and a non-zero value indicates an exception. The code example of the interface request is as follows:

    const eaxios = require('eaxios');
    
    eaxios.defaults.transformResponse = [
      function (data, response) {
        if (typeof data === 'object') {
          // 默认约定有成功解析 JSON 对象,就认为服务端成功响应,且有提供错误码
          if (data.code === 0) {
            return data.data;
          } else {
            throw eaxios.createError(data.message, data.code, response);
          }
        } else {
          // 50x 等服务异常情况
          throw eaxios.createError(
            data,
            response.config.responseError.SERVER_ERROR,
            response
          );
        }
      },
    ];
    
    return eaxios('https://run.mocky.io/v3/4f503449-0349-467e-a38a-c804956712b7')
      .then((data) => {
        console.log('success', data.id);
      })
      .catch((error) => {
        console.log('failure', error.code); // UNKNOWN、REQUEST_OFFLINE、REQUEST_TIMEOUT、SERVER_ERROR、RESPONSE_INVALID 和业务错误码
      });
ps:如果存在服务单接口请求规范,可以通过 eaxios.create 创建适用于不同接口规范的请求函数。
  • The eaxios request processing function then will only receive the transformed data of transformResponse. For network, timeout, server exceptions and business exceptions, it will receive an EaxiosError type error object in the catch.

    interface EaxiosError<T = any> extends Error {
      config: EaxiosRequestConfig;
      code?: string;
      request?: any;
      response?: EaxiosResponse<T>;
      isAxiosError: boolean;
      toJSON: () => object;
    }
错误处理函数可以根据错误码 code 来处理异常,code 可能的值为 UNKNOWN、REQUEST_OFFLINE、REQUEST_TIMEOUT、SERVER_ERROR、RESPONSE_INVALID 和其他业务错误码。

ps:如果要定制错误码,可以在请求配置中添加配置项 `responseError`。

```js
eaxios.defaults.responseError = {
  REQUEST_OFFLINE: '1'REQUEST_OFFLINE
};
```
  • Eaxios will automatically serialize the request parameters of the form type internally, so it is enough to pass the object to the data.

Code example

Let's take { code: 0, message: 'success', data: { } } as an example to demonstrate how to use eaxios.

const eaxios = require('..');

const request = eaxios.create({
  baseURL: 'https://run.mocky.io/v3',
  timeout: 30000,
  transformResponse: [
    function (data, response) {
      if (typeof data === 'object') {
        if (data.code === 0) {
          return data.data;
        } else {
          throw eaxios.createError(data.message, data.code, response);
        }
      } else {
        throw eaxios.createError(
          data,
          response.config.responseError.SERVER_ERROR,
          response,
        );
      }
    },
  ],
});

request.interceptors.response.use(
  function (response) {
    return response;
  },
  function (error) {
    if (error && error.code) {
      if (error.code === 'UNKNOWN') {
        console.log('未知错误');
      } else if (error.code === 'REQUEST_OFFLINE') {
        console.log('网络未连接');
      } else if (error.code === 'REQUEST_TIMEOUT') {
        console.log('网络有点慢,请求超时了');
      } else if (error.code === 'SERVER_ERROR') {
        console.log('系统出问题了');
      } else if (error.code === 'RESPONSE_INVALID') {
        console.log('服务端 bug');
      } else if (error.code === '10000') {
        // 假设 10000 为登录会话过期
        console.log('登录会话失效');
      } else {
        console.log('根据情况是否要消息提示,还是外部处理')
      }
    }
    throw error;
  },
);

function printError(error) {
  console.log(
    `code: ${error.code}, name: ${error.name}, message: ${error.message}, isAxiosError: ${error.isAxiosError}, stack:\n${error.stack}`,
  );
}

function success() {
  console.log('>> success');
  return request('/4f503449-0349-467e-a38a-c804956712b7')
    .then((data) => {
      console.log('success', data);
    })
    .catch((error) => {
      printError(error);
    });
}

function failure() {
  console.log('>> failure');
  return request('/42d7c21d-5ae6-4b52-9c2d-4c3dd221eba4')
    .then((data) => {
      console.log('success', data);
    })
    .catch((error) => {
      printError(error);
    });
}

function invalid() {
  console.log('>> invalid');
  return request('/1b23549f-c918-4362-9ac8-35bc275c09f0')
    .then((data) => {
      console.log('success', data);
    })
    .catch((error) => {
      printError(error);
    });
}

function server_500() {
  console.log('>> server_500');
  return request('/2a9d8c00-9688-4d36-b2de-2dee5e81f5b3')
    .then((data) => {
      console.log('success', data);
    })
    .catch((error) => {
      printError(error);
    });
}

success().then(failure).then(invalid).then(server_500);
/* log
>> success
success { id: 1 }
>> failure
登录会话失效
code: 10000, name: Error, message: error, isAxiosError: true, stack: ...
>> invalid
服务端 bug
code: RESPONSE_INVALID, name: SyntaxError, message: Unexpected token V in JSON at position 0, isAxiosError: true, stack: ...
>> server_500
系统出问题了
code: SERVER_ERROR, name: Error, message: ...,  stack: ...
*/

compatibility

eaxios relies on URLSearchParams to process form-type request parameters. Unsupported environments need to introduce response polyfills

code is deployed, the possible bugs cannot be known in real time. In order to solve these bugs afterwards, a lot of time was spent on log debugging. By the way, I would like to recommend a useful BUG monitoring tool Fundebug .

comminicate

World" on WeChat to read and update as soon as possible (one or two earlier than the blog). This article has been included on GitHub 16119b19101b04 https://github.com/qq449245884/xiaozhi I have sorted out a lot of my documents, welcome to Star and improve it. You can refer to the test site for review for interviews. In addition, pay attention to the account, and reply to 16119b19101b06 welfare background, you can see the welfare, you know.


王大冶
68.2k 声望105k 粉丝