In the previous chapter we introduced Axios source code interpretation – Request. In this chapter we will introduce the part where Axios actually initiates the network request, namely the dispatchRequest method.

dispatchRequest

This method definition is also relatively simple (figure below)

Line 29 — Cancel the request

Let’s parse what each line of code does line by line, starting with the cancellation request on line 29. (below)

throwIfCancellationRequested(config);
Copy the code

This action is done not only before the formal request is made, but also when the request succeeds and when the request fails.

As long as the request is cancelled, it will not enter the success or failure callback processing. (As shown below)

And do throwIfCancellationRequested function, is testing whether this request was cancelled, if cancelled it throws an error, continue to execute down and block code. (below)

function throwIfCancellationRequested(config) {
  if (config.cancelToken) {
    // Checks if the request is cancelled and decides whether to throw an error
    config.cancelToken.throwIfRequested();
  }

  if (config.signal && config.signal.aborted) {
    // Throw an error
    throw new Cancel('canceled'); }}Copy the code

Of course, the whole CancelToken implementation is a bit complicated (the complexity is in the callback handling). If you are interested, you can talk about this part of the CancelToken implementation separately.

Lines 35 to 40 — process the request data

config.data = transformData.call(
  config,
  config.data,
  config.headers,
  config.transformRequest
);
Copy the code

A transformData method is used here, which is used to merge data and can be merged using the configured transformRequest method (as shown in the following figure).

The transformData method iterates through the incoming transformRequest method, takes data and headers as input parameters, and copies the result to config.data. The data content to be sent as the last request.

Lines 43 to 54 — merge request HEADERS

config.headers = utils.merge(
  config.headers.common || {},
  config.headers[config.method] || {},
  config.headers
);

utils.forEach(
  ['delete'.'get'.'head'.'post'.'put'.'patch'.'common'].function cleanHeaderConfig(method) {
    deleteconfig.headers[method]; });Copy the code

The above code does two main things:

  • The first thing is going to be universalheaders(common headers) and corresponding methodsheadersAnd the originalheadersDid a merge;
  • The second thing is that after the merger is complete, it will be redundantheadersThe configuration is deleted.

Lines 56 to 58 — Make a real request

var adapter = config.adapter || defaults.adapter;

return adapter(config).then(function onAdapterResolution(response) {
  // ...
});
Copy the code

The configured Adapter is used here, which is how the request is initiated.

The two default request methods, for example, run using XMLHttpRequest on the browser side and HTTP modules on the Node side.

What can you do with this configuration?

You can pass in a custom request method here, for example using fetch encapsulation on the client side instead of XMLHttpRequest.

You can also pass in a mock method that you’ve wrapped, which returns native JSON data for your mock data, so you don’t have to build an extra mock service.

.

Without further discussion, let’s take a look at axios’s two default Adapters and focus on the client adapter, xhrAdapter.

Client Adapter — xhrAdapter

We parse the client Adapter, xhrAdapter, line by line as usual.

Preparation before making a request

The number of rows describe
The first16 ~ 18 Collect request data information (requestData), request headers (requestHeaders), return body type (responseType)
The first19 ~ 28 rightcancelTokenDo the processing and cancel the subscription when the request completes, freeing up memory; There are aboutsignalThe processing of thissignalIt’s not in the documentation anymore, so it should be usedabortThe request.
The first30 ~ 32 forFormDataRequest to removeContent-TypeRequest headers, which the browser automatically sets.

Example Set authentication information

First, at line 34, an XMLHttpRequest instance is created for subsequent network requests.

In line 37 to 41, we set the HTTP Basic authentication information.

First, encodeURLComponent escape encoding is performed for the password, and then the user name and password are splices according to rules. Btoa is used to transform the user name and password into Base64 encoding.

If you want to do this kind of thing yourself in the future, you can go back to this section to find this part of the code and copy it.

Concatenated request URL

The first is to concatenate the full request URL with the buildFullPath method. (As shown below)

As you can see, this method does not concatenate baseURL for absolute path urls (isAbsoluteURL()).

Axios then uses the buildURL method to concatenate the params parameter into the URL — also known as the Query parameter. (below)

function buildURL(url, params, paramsSerializer) {
  /*eslint no-param-reassign:0*/
  if(! params) {return url;
  }

  var serializedParams;
  if (paramsSerializer) {
    serializedParams = paramsSerializer(params);
  } else if (utils.isURLSearchParams(params)) {
    serializedParams = params.toString();
  } else {
    // ...

    serializedParams = parts.join('&');
  }

  if (serializedParams) {
    // ...
    // In this case, the processed parameters are concatenated to the URL as query query parameters
    url += (url.indexOf('? ') = = = -1 ? '? ' : '&') + serializedParams;
  }

  return url;
};
Copy the code

This is why when using Axios, the parameters of the GET method are set in the params field.

A request is then initialized using the request.open method.

Respond to the callback function

The next step is to compare the core response callback function (as shown below)

The number of rows describe
The first54 Gets all response headers
The first55 Get response content
The first57-64 Set up thepromise resolveContent is what you often doconsole.logThe stuff that came out should look familiar to you

Set other callback functions

This is basically all about setting the callbacks to the XMLHttpRequest object. (As shown below)

For those of you who are late to the front end, you may not know much about what you do with events such as XMLHttpRequest instances, refer to the XMLHttpRequest documentation.

Finally, send the request. (below)

request.send(requestData);
Copy the code

Back to dispatchRequest

As can be seen from the above, the dispatchRequest finally calls the Adapter and gets the following data.

{
  data: responseData,
  status: request.status,
  statusText: request.statusText,
  headers: responseHeaders,
  config: config,
  request: request
};
Copy the code

Then let’s take a look at how dispatchRequest handles this data internally. (As shown below)

The number of rows describe
The first59/72 Processing isCancelTokenA canceled request that does not proceed if the request has been canceled
The first62 ~ 67 Pass the response resulttransformResponseAfter conversion, the processed response data is obtained
The first69 Returns the result of the response

Now that the entire AXIos request flow is clear, let’s draw a flow chart to sort it out. (As shown below)

The adapter on the Node side will not be expanded here, and the differences between the client side and the Node side mainly lie in the following points:

  1. Using theNodehttpThe module initiates the request.
  2. Can be achieved byproxySet up the proxy server to which requests will be sent.

summary

Well, that’s where our interpretation of axios’ source code ends.

As you can see, axios is the most popular and powerful network request framework, but the source code looks relatively clean and easy to read, I suggest you can follow the ideas of the article to see.

In the next chapter, we’ll implement a simple AXIos framework that includes some of axios’s core functions and wrap up the Axios source code interpretation series.

One last thing

If you’ve already seen it, please give it a thumbs up

Your likes are the greatest encouragement to the author, and can also let more people see this article!

If you find this article helpful, please help to light up the star on Github.