“This is the second day of my participation in the First Challenge 2022.

First in my blog – big front-end engineer growth path – Axios-defaults source code

defaults The default config for the instance

Defaults Library function that initializes the default configuration of an instance

First, environmental preparation

  • Axios version v0.24.0

  • The source code for Axios is available on the Github1s page

  • The debugging needs to be clone to the local PC

git clone https://github.com/axios/axios.git

cd axios

npm start

http://localhost:3000/
Copy the code

Second, function study

1. The helper function

Includes utils, normalizeHeaderName, and enhanceError

【 1.1 】 utils

Utils is a generic helper library that is not specific to Axios. As the name implies, it contains some code segments unrelated to business logic but which may improve efficiency or be frequently used, called utility functions. For more on Axios’s utility library utils, see utils

【 1.2 】 normalizeHeaderName

var normalizeHeaderName = require('./helpers/normalizeHeaderName'); = = = >'use strict';

var utils = require('.. /utils');

module.exports = function normalizeHeaderName(headers, normalizedName) {
  utils.forEach(headers, function processHeader(value, name) {
    if(name ! == normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) { headers[normalizedName] = value;deleteheaders[name]; }}); };Copy the code
  • It normalizes the request headerHeaderIn thekeyName, substitution is not satisfiedAxiosInternally requiredkeyThe name
  • throughtoUpperCase()User – definedHeaderThe middle key name is converted to uppercase and corresponds to the default configuration inside AxioskeyUppercase comparison
  • forEachLoop key-value pairsheadersIs called back each timeprocessHeader, into the referencekey,valueThe correspondingheadersFor each of these termskeyandThe key value

ForEach is used in utils. Each call to normalizeHeaderName checks all headers keys once

【 1.3 】 enhanceError

var enhanceError = require('./core/enhanceError'); = = = >'use strict';

/**
 * Update an Error with the specified config, error code, and response.
 *
 * @param {Error} error The error to update.
 * @param {Object} config The config.
 * @param {string} [code] The error code (for example, 'ECONNABORTED').
 * @param {Object} [request] The request.
 * @param {Object} [response] The response.
 * @returns {Error} The error.
 */
module.exports = function enhanceError(error, config, code, request, response) {
  error.config = config;
  if (code) {
    error.code = code;
  }

  error.request = request;
  error.response = response;
  error.isAxiosError = true;

  error.toJSON = function toJSON() {
    return {
      // Standard
      message: this.message,
      name: this.name,
      // Microsoft
      description: this.description,
      number: this.number,
      // Mozilla
      fileName: this.fileName,
      lineNumber: this.lineNumber,
      columnNumber: this.columnNumber,
      stack: this.stack,
      // Axios
      config: this.config,
      code: this.code,
      status: this.response && this.response.status ? this.response.status : null
    };
  };
  return error;
};
Copy the code
  • The function is to organize the error information and make some supplementary statements to the error information
  • The error information provided by the compiler when Javscript execution fails may not always be perfect, For this see MDN – These errors can be a helpful debugging aid, but the reported problem isn’t always immediately clear.
  • How does the compiler detect JS runtime errors and throw them to the browserStackOverflowErrorStack overflow error speaks a good article, teacher Li Bing’s column -Heap and stack: How do function calls affect memory layout?

2. The body

[2.1] Constant

var DEFAULT_CONTENT_TYPE = {
    "Content-Type": "application/x-www-form-urlencoded"};Copy the code

  • Due to thehttpThe protocol stipulates that the web page transmission content is transmitted in text form, so the transmission content needs to be agreedbodyThe format of the
  • Content-TypeIs a required field that needs to have a default value, differentContent-TypeimpactbodyThe format of the
  • Cntent-Type The default is specified asapplication/x-www-form-urlencodedThe submitted data is encoded according to key1=val1&key2=val2, which has good compatibility

[2.2] Internal function setContentTypeIfUnset

function setContentTypeIfUnset(headers, value) {
    if (
        !utils.isUndefined(headers) &&
        utils.isUndefined(headers["Content-Type"])
    ) {
        headers["Content-Type"] = value; }}Copy the code
  • Using theutilsIn theisUndefinedMethod to determine whether data is defined
  • Request headerheadersThere are definitions but there areContent-TypeUndefined, need to set initial valueval

[2.3] Internal function getDefaultAdapter

function getDefaultAdapter() {
    var adapter;
    if (typeofXMLHttpRequest ! = ="undefined") {
        // For browsers use XHR adapter
        adapter = require("./adapters/xhr");
    } else if (
        typeofprocess ! = ="undefined" &&
        Object.prototype.toString.call(process) === "[object process]"
    ) {
        // For node use HTTP adapter
        adapter = require("./adapters/http");
    }
    return adapter;
}
Copy the code
  • Depending on the host environment[Browser, node]Get the adapter, which can be interpreted as creating one for interacting with the serverInstance objects
  • More information about adapters can be found atMDNTake a look at onThe Browser (Browser)thexhr(XMLHttpRequest)

Tips: Don’t get too entangled in the concept of adapters, future articles will delve into adapters for [Browser, Node]

[2.4] Internal function stringifySafely

function stringifySafely(rawValue, parser, encoder) {
    if (utils.isString(rawValue)) {
        try {
            (parser || JSON.parse)(rawValue);
            return utils.trim(rawValue);
        } catch (e) {
            if(e.name ! = ="SyntaxError") {
                throwe; }}}return (encoder || JSON.stringify)(rawValue);
}
Copy the code
  • stiffenedrawValueIn other words, remove the leading space
  • Using customparserorJSON.parseParse the JSON string into the correspondingvalueorobject
  • If the string does not conform to the JSON specification, wheretry {} catch()Will catch and throw a SyntaxError exception, otherwise calledutilsIn thetrimThe function removes the leading whitespace
  • Use custom when returningencoderorJSON.stringifythenrawValueConverted toJsonstring

There is no custom Parser and Encoder available in the source code so far 🐶

[2.5] Construct object defaults

Here is the body of the default configuration

var defaults = {
    transitional: {
        silentJSONParsing: true.forcedJSONParsing: true.clarifyTimeoutError: false,},adapter: getDefaultAdapter(),

    transformRequest: [
        function transformRequest(data, headers) {
            normalizeHeaderName(headers, "Accept");
            normalizeHeaderName(headers, "Content-Type");

            if (
                utils.isFormData(data) ||
                utils.isArrayBuffer(data) ||
                utils.isBuffer(data) ||
                utils.isStream(data) ||
                utils.isFile(data) ||
                utils.isBlob(data)
            ) {
                return data;
            }
            if (utils.isArrayBufferView(data)) {
                return data.buffer;
            }
            if (utils.isURLSearchParams(data)) {
                setContentTypeIfUnset(
                    headers,
                    "application/x-www-form-urlencoded; charset=utf-8"
                );
                return data.toString();
            }
            if (
                utils.isObject(data) ||
                (headers && headers["Content-Type"= = ="application/json")
            ) {
                setContentTypeIfUnset(headers, "application/json");
                return stringifySafely(data);
            }
            returndata; },].transformResponse: [
        function transformResponse(data) {
            var transitional = this.transitional || defaults.transitional;
            var silentJSONParsing =
                transitional && transitional.silentJSONParsing;
            var forcedJSONParsing =
                transitional && transitional.forcedJSONParsing;
            varstrictJSONParsing = ! silentJSONParsing &&this.responseType === "json";

            if (
                strictJSONParsing ||
                (forcedJSONParsing && utils.isString(data) && data.length)
            ) {
                try {
                    return JSON.parse(data);
                } catch (e) {
                    if (strictJSONParsing) {
                        if (e.name === "SyntaxError") {
                            throw enhanceError(e, this."E_JSON_PARSE");
                        }
                        throwe; }}}returndata; },]./** * A timeout in milliseconds to abort a request. If set to 0 (default) a * timeout is not created. */
    timeout: 0.xsrfCookieName: "XSRF-TOKEN".xsrfHeaderName: "X-XSRF-TOKEN".maxContentLength: -1.maxBodyLength: -1.validateStatus: function validateStatus(status) {
        return status >= 200 && status < 300;
    },

    headers: {
        common: {
            Accept: "application/json, text/plain, */*",}}};Copy the code
  • This is the request headerheaderAnd transmission contentdataSome processing is done, and some configuration initialization is done
  • transitionalIncludes some overattribute configuration items that are not visible to developers, mainly for compatibility with previous releases, and can be configured to remove backward compatibility properties in newer releases
  • transformResponseMaking some changes to the data before sending the request to the server changes the content of the requestdataDo some formatting and convert it to a format that the server can easily acceptutilsFunction library analysis
  • transformResponseMainly based ontransitionalThe configuration makes some formatting changes to the returned content and adds some explanatory notes to the error message if an error occurs
Configuration items role
[transitional-silentJSONParsing] Version compatible configuration – Whether null is returned when converting the return value to Json fails
[transitional-forcedJSONParsing] Version compatible configuration -responseType Sets whether a non-JSON type is cast to JSON format
[transitional-clarifyTimeoutError] Version Compatibility Configuration – Whether ETIMEDOUT type error is returned by default when a request times out
adapter Choose the default adapter, noting that custom processing requests are allowed
transformRequest Allows request data to be modified before being sent to the server
transformResponse Response data is allowed to be modified before being passed to then/catch
timeout Specifies the number of milliseconds in which the request timed out (0 means no timeout)
xsrfCookieName The name of the cookie used as the value of the XSRF token
xsrfHeaderName The name of the HTTP header that holds the XSRF token value
maxContentLength Defines the maximum size allowed for response content
maxBodyLength Default maximum body length limit
validateStatus Define resolve or Reject or PROMISE for a given HTTP response status code
[headers-common-Accept] “object”

Tips: For more instructions on configuration, see AxiOS Request Configuration, and Axios Readme

[2.6] Internal function stringifySafely

utils.forEach(["delete"."get"."head"].function forEachMethodNoData(method) {
    defaults.headers[method] = {};
});

utils.forEach(["post"."put"."patch"].function forEachMethodWithData(method) {
    defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
});
Copy the code
  • Here the request header is initialized for several requests, [delete.get.head] three request headers that do not require submission of form contentheaderIs empty,post.put.patch] three request headers that require submission of form contentheadersetContent-Typeforapplication/x-www-form-urlencoded, very well understood, not to repeat too much

Three, reference

1. Read and analyze the tool function utils of my article

Google V8 – How do function calls affect memory layout

3. Teacher Winter’s front end Boot Camp – notes I summarized

4. MDN