axios学习笔记

axios的配置

aixos官网教程:https://github.com/axios/axios

axios是用来发送Ajax请求的,可以运行在浏览器和Node.js环境中。

如果想要在不同环境中使用axios,需要不同的引入方式:

  • 如果是在浏览器中使用,可通过如下代码引入:
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>axios配置</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<script>
    console.log(axios);
</script>
</body>
</html>

在这里插入图片描述

  • 如果是在Node.js中使用,则可通过下面的代码引入:
// 第一步,安装包
npm install axios

// 第二步,引入使用
var axios = require('axios');

axios基本使用

发送GET请求

例如http://poetry.apiopen.top/poetryAuthor?count=2&page=1&name=李白接口可以获取指定作者的诗词信息,是一个GET请求,正好可以用来测试axios。对于GET请求中参数的处理可以有如下两种方式:

  • 参数直接写在URL中

语法格式如下:

    /**
     * 其中url是你要请求的URL,其中参数是拼接在URL中的
     */
    axios.get(url)
        .then(function (response) {
            // response是响应回来的数据
        })
        .catch(function (error) {
            // error是错误对象
        });

浏览器使用示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>axios学习</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<script>
    axios.get('http://poetry.apiopen.top/poetryAuthor?count=2&page=1&name=李白')
        .then(function (response) {
            console.log(response);
        })
        .catch(function (error) {
            console.log(error);
        });
</script>
</body>
</html>

Node.js环境中使用代码如下:

var axios = require('axios');

axios.get('http://poetry.apiopen.top/poetryAuthor?count=2&page=1&name='+encodeURIComponent("李白"))
    .then(function (response) {
        console.log(response);
    })
    .catch(function (error) {
        console.log(error);
    });
  • 请求参数单独列出来

语法如下:

    axios.get(请求URL, {
        params: {
            参数名: 参数值,
            参数名: 参数值
            }
        })
        .then(function (response) {
            // response是响应回来的数据
        })
        .catch(function (error) {
            // error是错误对象
        });

示例如下:

var url = 'http://poetry.apiopen.top/poetryAuthor';
var result = axios.get(url, {
    params: {
        count: 2,
        page: 1,
        name: encodeURIComponent("李白")
        }
    })
    .then(function (response) {
        // 数据是保存在data属性上的
        console.log(response.data);
    }).catch(function (error) {
        console.log(error);
    });

注:我们还可以使用asyncawait的方式获取axios.get()响应返回的数据,但要求是ES7以上,并且有一些浏览器不支持,需要注意。

var url = 'http://poetry.apiopen.top/poetryAuthor?count=2&page=1&name=' + encodeURIComponent("李白");

// 使用async和await关键字封装axios.get()操作
async function getAuthor(url) {
    try {
        // axios.get()方法返回的是一个Promise对象,所以可以使用async和await来获取
        var res = await axios.get(url);
        // 真正我们想要的数据在data属性上
        console.log(res.data);
    } catch (e) {
        console.log(e);
    }
}

getAuthor(url);// 调用上面封装的方法

发送POST请求

我们以下面这个接口来进行测试发送POST请求:https://api.apiopen.top/searchPoetry
在这里插入图片描述

发送POST请求的基本语法如下:

axios.post(请求URL, {
    参数名: 参数值,
    参数名: 参数值
    })
    .then(function (response) {
        // response是响应回来的数据
    })
    .catch(function (error) {
        // error是当发生错误时输出的错误对象
    });

示例代码如下:

var url = 'https://api.apiopen.top/searchPoetry';
axios.post(url, {name: '李白'})
    .then(function (response) {
        console.log(response.data);
    })
    .catch(function (error) {
        console.log(error);
    });

注意,利用Promise还可以执行多个并发请求,示例如下:

var url1 = 'http://poetry.apiopen.top/poetryAuthor?count=2&page=1&name=' + encodeURIComponent("李白");
var url2 = 'http://poetry.apiopen.top/poetryAuthor?count=2&page=1&name=' + encodeURIComponent("杜甫");

var libai = axios.get(url1);
var dufu = axios.get(url2);

// 因为axios.get()方法返回的是Promise对象,所以可以使用Promise.all()语法来执行并发请求
Promise.all([libai, dufu])
    .then(function (results) {
        console.log(results[0].data);
        console.log(results[1].data);
    });

axios的API

axios()

可以直接将请求URL、请求方法、请求参数等信息直接传到axios()方法,不必单独再使用其他API。语法如下:

axios(config)

其中config是一个对象,是请求URL、请求方法、请求参数等配置信息。

  • 例如,发送一个GET请求
var url = 'http://poetry.apiopen.top/poetryAuthor';

axios({
    // method属性表示设置请求方式
    method: 'get',
    // url属性表示设置请求URL
    url: url,
    // data属性是一个对象,用来设置请求参数
    data: {
        count: 2,
        page: 1,
        name: encodeURIComponent("李白")
        }
    })
    // axios()方法返回一个Promise对象,所以可以使用then方法获取响应数据
    .then(function (response) {
        console.log(response.data);
    })
    .catch(function (error) {
        console.log(error);
    });
  • 例如,发送一个POST请求
var url = 'https://api.apiopen.top/searchPoetry';

axios({
    // method属性表示设置请求方式
    method: 'post',
    // url属性表示设置请求URL
    url: url,
    // data属性是一个对象,用来设置请求参数
    data: {
        name: '李白'
    },
    // responseType属性表示设置响应数据类型
    responseType: 'json'
})
// axios()方法返回一个Promise对象,所以可以使用then方法获取响应数据
.then(function (response) {
    console.log(response.data);
})
.catch(function (error) {
    console.log(error);
});

除了上面那一种语法之外,axios()方法还有一种语法,如下:

axios(url[, config])

其中config是可选项,默认发送GET请求。

axios.get()axios.post()

为了方便起见,为常用方法方法设置了别名方法,如axios.get()就直接表示发送GET请求。这些方法如下:

  • axios.request(config)
  • axios.get(url[, config])
  • axios.delete(url[, config])
  • axios.head(url[, config])
  • axios.options(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])
  • axios.patch(url[, data[, config]])

当使用上述方法发送请求时,urlmethoddata属性不必单独在config参数种标明,因为该方法的参数和名字已经特别说明了。例如GET请求的示例如下:

var url = 'http://poetry.apiopen.top/poetryAuthor';
var result = axios.get(url, {
    params: {
        count: 2,
        page: 1,
        name: encodeURIComponent("李白")
        }
    })
    .then(function (response) {
        // 数据是保存在data属性上的
        console.log(response.data);
    }).catch(function (error) {
        console.log(error);
    });

axios.create()

可以使用自定义配置创建新的axios实例,而上面使用的axios.get()等方法中的axios都是默认提供的实例。如果要自定义axios实例,使用create()方法,语法如下:

// 这里的axios还是默认实例
axios.create([config])

例如:

var instance=axios.create({
    baseUrl:'https://api.apiopen.top/',
    timeout:1000,
    headers:{'X-Custom-Header': 'foobar'}
});

下面列出了可用的实例方法,指定的配置将与实例配置合并。

  • axios#request(config)
  • axios#get(url[, config])
  • axios#delete(url[, config])
  • axios#head(url[, config])
  • axios#options(url[, config])
  • axios#post(url[, data[, config]])
  • axios#put(url[, data[, config]])
  • axios#patch(url[, data[, config]])
  • axios#getUri([config])

示例如下:

var axios = require('axios');

var axiosInstance = axios.create({
    baseURL: 'http://poetry.apiopen.top/',
    timeout: 1000
});
axiosInstance
    .get('/sentences')
    .then(function (res) {
        console.log(res.data)
    });

请求中的config参数和响应中的reponse参数

Request Config

即请求中的config参数,该参数是一个对象,可以设置请求属性,如urlmethod等。可以设置的属性说明:

{
  // `url` 是用于请求的服务器 URL
  url: "/user",

  // `method` 是创建请求时使用的方法
  method: "get", // 默认是 get

  // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
  // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
  baseURL: "https://some-domain.com/api/",

  // `transformRequest` 允许在向服务器发送前,修改请求数据
  // 只能用在 "PUT", "POST" 和 "PATCH" 这几个请求方法
  // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
  transformRequest: [function (data) {
    // 对 data 进行任意转换处理

    return data;
  }],

  // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
  transformResponse: [function (data) {
    // 对 data 进行任意转换处理

    return data;
  }],

  // `headers` 是即将被发送的自定义请求头
  headers: {"X-Requested-With": "XMLHttpRequest"},

  // `params` 是即将与请求一起发送的 URL 参数
  // 必须是一个无格式对象(plain object)或 URLSearchParams 对象
  params: {
    ID: 12345
  },

  // `paramsSerializer` 是一个负责 `params` 序列化的函数
  // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
  paramsSerializer: function(params) {
    return Qs.stringify(params, {arrayFormat: "brackets"})
  },

  // `data` 是作为请求主体被发送的数据
  // 只适用于这些请求方法 "PUT", "POST", 和 "PATCH"
  // 在没有设置 `transformRequest` 时,必须是以下类型之一:
  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - 浏览器专属:FormData, File, Blob
  // - Node 专属: Stream
  data: {
    firstName: "Fred"
  },

  // `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
  // 如果请求话费了超过 `timeout` 的时间,请求将被中断
  timeout: 1000,

  // `withCredentials` 表示跨域请求时是否需要使用凭证
  withCredentials: false, // 默认的

  // `adapter` 允许自定义处理请求,以使测试更轻松
  // 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)).
  adapter: function (config) {
    /* ... */
  },

  // `auth` 表示应该使用 HTTP 基础验证,并提供凭据
  // 这将设置一个 `Authorization` 头,覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头
  auth: {
    username: "janedoe",
    password: "s00pers3cret"
  },

  // `responseType` 表示服务器响应的数据类型,可以是 "arraybuffer", "blob", "document", "json", "text", "stream"
  responseType: "json", // 默认的

  // `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称
  xsrfCookieName: "XSRF-TOKEN", // default

  // `xsrfHeaderName` 是承载 xsrf token 的值的 HTTP 头的名称
  xsrfHeaderName: "X-XSRF-TOKEN", // 默认的

  // `onUploadProgress` 允许为上传处理进度事件
  onUploadProgress: function (progressEvent) {
    // 对原生进度事件的处理
  },

  // `onDownloadProgress` 允许为下载处理进度事件
  onDownloadProgress: function (progressEvent) {
    // 对原生进度事件的处理
  },

  // `maxContentLength` 定义允许的响应内容的最大尺寸
  maxContentLength: 2000,

  // `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject  promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte
  validateStatus: function (status) {
    return status >= 200 && status < 300; // 默认的
  },

  // `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目
  // 如果设置为0,将不会 follow 任何重定向
  maxRedirects: 5, // 默认的

  // `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项:
  // `keepAlive` 默认没有启用
  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true }),

  // "proxy" 定义代理服务器的主机名称和端口
  // `auth` 表示 HTTP 基础验证应当用于连接代理,并提供凭据
  // 这将会设置一个 `Proxy-Authorization` 头,覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。
  proxy: {
    host: "127.0.0.1",
    port: 9000,
    auth: : {
      username: "mikeymike",
      password: "rapunz3l"
    }
  },

  // `cancelToken` 指定用于取消请求的 cancel token
  // (查看后面的 Cancellation 这节了解更多)
  cancelToken: new CancelToken(function (cancel) {
  })
}

注意:

  • 其中url是必选项,其他都是可选项。
  • 如果没有指定method属性的值,则默认发送GET请求。
  • 常用属性有:
    • url用于指定请求URL;
    • method用于指定请求方式,如GET、POST、PUT等;
    • baseURL通常用于axios.create()方法中,用于指定域名和端口号;
    • headers用于指定请求头;
    • params指定连接在URL后面的参数,通常用在axios.get()方法中;
    • data用于指定提交的数据,通常用于POST、PUT、PATCH请求;
    • timeout指定请求超时毫秒数;
    • responseType指定响应数据类型,默认是json;
    • withCredentials在跨域时会用到,如果是一个前后端分离的项目,通常要修改它来解决跨越问题。

Response Schema

var url = 'http://poetry.apiopen.top/sentences';
axios.get(url).then(function (response) {
    console.log(response);
});

即响应回来的数据response,它打印的结果如下:

{
  status: 200,
  statusText: 'OK',
  headers: {
    'access-control-allow-credentials': 'true',
    'access-control-allow-headers': 'Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With, Token, Language, From',
    'access-control-allow-methods': 'POST, OPTIONS, GET, PUT',
    'access-control-allow-origin': '*',
    'content-type': 'application/json; charset=UTF-8',
    date: 'Sun, 21 Nov 2021 05:27:12 GMT',
    'content-length': '140',
    connection: 'close'
  },
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [Function: httpAdapter],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    validateStatus: [Function: validateStatus],
    headers: {
      Accept: 'application/json, text/plain, */*',
      'User-Agent': 'axios/0.24.0'
    },
    method: 'get',
    url: 'http://poetry.apiopen.top/sentences',
    data: undefined
  },
  request: <ref *1> ClientRequest {
    _events: [Object: null prototype] {
      abort: [Function (anonymous)],
      aborted: [Function (anonymous)],
      connect: [Function (anonymous)],
      error: [Function (anonymous)],
      socket: [Function (anonymous)],
      timeout: [Function (anonymous)],
      prefinish: [Function: requestOnPrefinish]
    },
    _eventsCount: 7,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    destroyed: false,
    _last: true,
    chunkedEncoding: false,
    shouldKeepAlive: false,
    maxRequestsOnConnectionReached: false,
    _defaultKeepAlive: true,
    useChunkedEncodingByDefault: false,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    _contentLength: 0,
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    _closed: false,
    socket: Socket {
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'poetry.apiopen.top',
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      _writableState: [WritableState],
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: null,
      _server: null,
      parser: null,
      _httpMessage: [Circular *1],
      [Symbol(async_id_symbol)]: 3,
      [Symbol(kHandle)]: [TCP],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(RequestTimeout)]: undefined
    },
    _header: 'GET /sentences HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'User-Agent: axios/0.24.0\r\n' +
      'Host: poetry.apiopen.top\r\n' +
      'Connection: close\r\n' +
      '\r\n',
    _keepAliveTimeout: 0,
    _onPendingData: [Function: nop],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 80,
      protocol: 'http:',
      options: [Object: null prototype],
      requests: [Object: null prototype] {},
      sockets: [Object: null prototype],
      freeSockets: [Object: null prototype] {},
      keepAliveMsecs: 1000,
      keepAlive: false,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      scheduling: 'lifo',
      maxTotalSockets: Infinity,
      totalSocketCount: 1,
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'GET',
    maxHeaderSize: undefined,
    insecureHTTPParser: undefined,
    path: '/sentences',
    _ended: true,
    res: IncomingMessage {
      _readableState: [ReadableState],
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      socket: [Socket],
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      rawHeaders: [Array],
      rawTrailers: [],
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 200,
      statusMessage: 'OK',
      client: [Socket],
      _consuming: false,
      _dumped: false,
      req: [Circular *1],
      responseUrl: 'http://poetry.apiopen.top/sentences',
      redirects: [],
      [Symbol(kCapture)]: false,
      [Symbol(kHeaders)]: [Object],
      [Symbol(kHeadersCount)]: 16,
      [Symbol(kTrailers)]: null,
      [Symbol(kTrailersCount)]: 0,
      [Symbol(RequestTimeout)]: undefined
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: false,
    host: 'poetry.apiopen.top',
    protocol: 'http:',
    _redirectable: Writable {
      _writableState: [WritableState],
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _options: [Object],
      _ended: true,
      _ending: true,
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 0,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function (anonymous)],
      _currentRequest: [Circular *1],
      _currentUrl: 'http://poetry.apiopen.top/sentences',
      [Symbol(kCapture)]: false
    },
    [Symbol(kCapture)]: false,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      'user-agent': [Array],
      host: [Array]
    }
  },
  data: {
    code: 200,
    message: '成功!',
    result: { name: '先生醉也,童子扶者。', from: '曹德《三棒鼓声频·题渊明醉归图》' }
  }
}

下面就是对response这个对象的属性进行说明,axios请求的响应包含信息如下:

{
  // `data` 由服务器提供的响应
  data: {},

  // `status`  HTTP 状态码
  status: 200,

  // `statusText` 来自服务器响应的 HTTP 状态信息
  statusText: "OK",

  // `headers` 服务器响应的头
  headers: {},

  // `config` 是为请求提供的配置信息
  config: {}
}

使用 then 时,会接收下面这样的响应,通常我们只需要data属性即可:

var url = 'http://poetry.apiopen.top/sentences';
axios.get(url).then(function (response) {
    console.log(response.data);
    console.log(response.status);
    console.log(response.statusText);
    console.log(response.headers);
    console.log(response.config);
});

默认配置项

在各个请求中可以配置默认值。

全局axios默认值

配置语法格式如下:axios.defaults.属性名=属性值;。例如:

// 设置了baseURL之后,后面的请求只需要给一个相对URL就可以,axios会自动加在我们请求的URL前面形成一个完整的请求地址,指定这个后,就算后面修改域名和端口号只需要改这一处,而不是所有的请求路径
axios.defaults.baseURL = 'http://poetry.apiopen.top';
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

axios.get('/sentences').then(function (response) {
    console.log(response.data);
});

自定义实例默认值

上面我们知道可以通过axios.create()方法创建axios实例,所以可以在创建实例时设置配置项的默认值。例如:

// 创建实例时设置配置的默认值
var axiosInstance = axios.create({
    baseURL: 'http://poetry.apiopen.top'
});
// 在实例已经创建后修改默认值
axiosInstance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

// 使用axios实例进行请求
axiosInstance.get('/sentences').then(function (response) {
    console.log(response.data);
});

配置项的优先级

我们可以在下面这三处进行配置:

  • axios.get()等方法中的config参数
  • lib/defaults.js中的库默认值
  • axios.create()创建实例后通过defaults属性进行配置时

配置将按优先顺序合并。顺序是lib/defaults.js中的库默认值,然后是实例的defaults属性,最后是请求的config参数。后者将优先于前者。

// 使用由库提供的配置的默认值来创建实例
// 此时超时配置的默认值是 `0`
var instance = axios.create();

// 覆写库的超时默认值
// 现在,在超时前,所有请求都会等待 2.5 秒
instance.defaults.timeout = 2500;

// 为已知需要花费很长时间的请求覆写超时设置
instance.get("/longRequest", {
  timeout: 5000
});

拦截器

基本使用

可以在请求被处理之前和响应数据被渲染之前进行拦截,然后针对请求参数和响应结果进行一些处理。跟Java的Servlet的过滤器和SpringMVC的拦截器功能类似。axios拦截器分为请求拦截器和响应拦截器,即在请求时和响应时进行拦截,基本语法如下:

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么,config就是请求配置项
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做些什么,response是响应数据对象
    return response;
}, function (error) {
    // 对响应错误做些什么
    return Promise.reject(error);
});

例如:

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么,config就是请求配置项
    // 我们打印下请求配置项的请求方法和请求路径
    console.log(config.method + "\t", config.url);
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做些什么,response是响应数据对象
    if (parseInt(response.code) !== 200) {
        response.msg = "响应失败";
    }
    return response;
}, function (error) {
    // 对响应错误做些什么
    return Promise.reject(error);
});

var url = 'http://poetry.apiopen.top/sentences';
axios.get(url).then(function (response) {
    console.log(response.msg);
});
/*打印结果:
get	 http://poetry.apiopen.top/sentences
响应失败
 */

多个拦截器的执行顺序

如果拦截器的定义顺序是:请求拦截器1号——>请求拦截器2号——>…——>请求拦截器n号——>请求处理——>响应拦截器1号——>响应拦截器2号——>…——>响应拦截器n号,那么这些拦截器的执行顺序是:请求拦截器n号——>…——>请求拦截器2号——>请求拦截器1号——>请求处理——>响应拦截器1号——>响应拦截器2号——>…——>响应拦截器n号

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    console.log('请求拦截器1号');
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});
axios.interceptors.request.use(function (config) {
    console.log('请求拦截器2号');
    return config;
}, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
});

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    console.log('响应拦截器1号');
    return response;
}, function (error) {
    // 对响应错误做些什么
    return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
    console.log('响应拦截器2号');
    return response;
}, function (error) {
    // 对响应错误做些什么
    return Promise.reject(error);
});

var url = 'http://poetry.apiopen.top/sentences';
axios.get(url).then(function (response) {

});
/*打印结果:
请求拦截器2号
请求拦截器1号
响应拦截器1号
响应拦截器2号
 */

其他

如果你想在稍后移除拦截器,可以这样:

var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

可以为自定义 axios 实例添加拦截器:

var instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

错误处理

axios是能进行错误处理的,如axios()axios.get()axios.post()等方法返回的是一个Promise对象。

var url = 'http://poetry.apiopen.top/sentences';
var result = axios.get(url);
console.log(result);// Promise { <pending> }

所以可以使用Promise.catch()方法来处理错误,例如:

var url = 'http://poetry.apiopen.top/sentences1';
axios.get(url)
    .then(function (response) {
        // 对响应数据进行处理
    })
    .catch(function (error) {
        // 处理错误
        if (error.response) {
            // 请求已经发出,但服务器响应的状态码不在2xx范围内
            console.log(error.response.data);
            console.log(error.response.status);
            console.log(error.response.headers);
        } else if (error.request) {
            // 发出了请求,但没有收到任何答复
            //'error.request'是浏览器中的XMLHttpRequest的实例,也是node.js种http.ClientRequest的实例
            console.log(error.request);
        } else {
            // 设置触发错误的请求时发生了一些问题
            console.log(error.message);
        }
    });

可以使用 validateStatus 配置选项定义一个自定义 HTTP 状态码的错误范围:

axios.get("/user/12345", {
  validateStatus: function (status) {
    return status < 500; // 状态码在大于或等于500时才会 reject
  }
})

使用toJSON可以获得一个包含有关HTTP错误的更多信息的对象。

axios.get('/user/12345')
  .catch(function (error) {
    console.log(error.toJSON());
  });

取消请求

我们可以在发送请求之后再取消请求,避免用户恶意重复请求,造成服务器压力。例如:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>取消请求</title>
    <link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
    <div class="container">
        <h2 class="page-header">axios取消请求</h2>
        <button class="btn btn-primary"> 发送请求 </button>
        <button class="btn btn-warning" > 取消请求 </button>
    </div>
    <script>
        //获取按钮
        const btns = document.querySelectorAll('button');
        //2.声明全局变量
        let cancel = null;
        //发送请求
        btns[0].onclick = function(){
            //检测上一次的请求是否已经完成
            if(cancel !== null){
                //取消上一次的请求
                cancel();
            }
            axios({
                method: 'GET',
                url: 'http://localhost:3000/posts',
                //1. 添加配置对象的属性
                cancelToken: new axios.CancelToken(function(c){
                    //3. 将 c 的值赋值给 cancel
                    cancel = c;
                })
            }).then(response => {
                console.log(response);
                //将 cancel 的值初始化
                cancel = null;
            })
        }

        //绑定第二个事件取消请求
        btns[1].onclick = function(){
            cancel();
        }
    </script>   
</body>
</html>

请求时使用 application/x-www-form-urlencoded

axios会默认序列化 JavaScript 对象为 JSON. 如果想使用 application/x-www-form-urlencoded 格式,你可以使用下面的配置。但在浏览器环境和node.js环境的使用方法有所不同:

浏览器

在浏览器环境,你可以使用 URLSearchParams API :

const params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);

但注意,URLSearchParams不是所有的浏览器均支持。或者,您可以使用qs库对数据进行编码:

const qs = require('qs');
axios.post('/foo', qs.stringify({ 'bar': 123 }));

或者在ES6下:

import qs from 'qs';
const data = { 'bar': 123 };
const options = {
  method: 'POST',
  headers: { 'content-type': 'application/x-www-form-urlencoded' },
  data: qs.stringify(data),
  url,
};
axios(options);

Node.js

Query string

在node.js种,可以使用querystring模块来处理:

const querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));

或者使用url模块的URLSearchParams方法处理:

const url = require('url');
const params = new url.URLSearchParams({ foo: 'bar' });
axios.post('http://something.com/', params.toString());

在node.js中也是可以使用qs库。

Form data

或者使用form-data模块:

const FormData = require('form-data');
 
const form = new FormData();
form.append('my_field', 'my value');
form.append('my_buffer', new Buffer(10));
form.append('my_file', fs.createReadStream('/foo/bar.jpg'));

axios.post('https://example.com', form, { headers: form.getHeaders() })

或者使用拦截器

axios.interceptors.request.use(config => {
  if (config.data instanceof FormData) {
    Object.assign(config.headers, config.data.getHeaders());
  }
  return config;
});

参考资源

特别说明

  • 重点学习axios的配置axios基本使用axios的API,后面的了解性学习,先会用,再深入。
  • 初学者不必太过于在意视频中的手写实现axios。
  • axios是基于Promise的,所以必须先学会Promise再使用axios更能理解。
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果要学习axios,首先需要了解它是什么以及它的作用。axios是一个基于Promise的HTTP客户端,用于发起HTTP请求并处理响应。它可以在浏览器端和Node.js环境中使用,可以实现对服务器的GET、POST、PUT、DELETE等不同类型的请求。 要学习axios,可以从以下几个方面入手: 1. 安装和导入:首先需要通过npm或者yarn安装axios,然后在需要使用它的文件中,使用import或者require语句导入axios模块。 2. 发送请求:使用axios发送请求非常简单,只需要调用axios的方法并传入请求的URL和其他必要参数即可。例如,可以使用axios.get()发送一个GET请求,axios.post()发送一个POST请求等。 3. 处理响应:axios可以返回一个Promise对象,可以通过调用.then()方法来处理成功的响应,通过调用.catch()方法来处理失败的响应。在.then()中可以获取到服务器返回的数据,并进行相应的操作。 4. 配置请求:axios支持通过配置项来进行请求的设置,如设置请求头、超时时间等。可以在请求时传入一个具有特定配置的对象,以覆盖默认的配置。 5. 拦截器:axios还可以通过使用拦截器来在请求发送前和响应返回后对请求和响应进行全局的处理。可以通过axios.interceptors.request.use()注册请求拦截器,通过axios.interceptors.response.use()注册响应拦截器。 6. 错误处理:当请求出现错误时,axios会返回一个失败的Promise。可以通过.catch()方法捕获错误,并进行错误处理。 最后,还可以查看axios的官方文档,其中包含了详细的用法和示例代码,可以更加深入地了解和学习axios的使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值