$ ls ~yifei/notes/

Axios 的基本使用

Posted on:

Last modified:

虽然在现代浏览器中,fetch 已经支持很好了,但是 API 还是没有那么好用。比如说增加 GET 参数 必须使用 URLSearchParm 这个类。相比之下,Axios 的 API 更接近直觉一些。

import axios from 'axios'

axios(url, [config]);
axios(config);
axios.get(url, [config])
axios.delete(url, [config])
axios.put(url, data, [config])
axios.post(url, data, [config])

// 请求中 config 的属性
const config = {
    headers: {}, // Headers
    params: {},  // GET 参数
    data: {},  // 默认情况下 {} 会按照 JSON 发送
    timeout: 0, // 默认是没有 timeout 的
}

// 如果要发送传统的 POST 表单
const config = {
    data: new FormData()
}

// headers 会根据 data 是 json 还是表单自动设置,非常贴心。

// 响应的属性
let res = await axios.get("/api")
res = {
    data: {},  // axios 会自动 JSON.parse
    status: 200,
    statusText: "OK",
    headers: {},
    config: {},
    request: {}
}
// 和 fetch 不同的是,res.data 可以直接使用,而 fetch 还需要 await res.json()

// 如果要添加一些默认的设置,使用
axios.defaults.headers.common["X-HEADER"] = "value"
axios.defaults.timeout = 3000
// 具体参见这里: https://github.com/axios/axios/blob/master/lib/defaults.js#L28

重定向与其他错误状态码

对于 3XX 重定向代码,axios 只能跟中,这是浏览器决定的,不是 axios 可以改变的。 对于 4XX 和 5XX 状态码,axios 会抛出异常,可以 catch 住。

Get 参数

由于 GET 参数存在多种 null 状态,比如直接不包含,为空等等,axios 做了对应映射:

{ key: undefined } to ? (not included)
{ key: null }      to ?key
{ key: '' }        to ?key=
{ key: 'null' }    to ?key=null

上传文件

传统的表单编码格式:

const formData = new FormData();
const fileElement = document.querySelector('#my-file');

// 这里的 file 是 File 类型的一个对象,可以用 new File 构造
for (const file of fileElement.files) {
    formData.append("my-file", file);  // 同一个名字可以对应多个文件,后端也可以读取到
}
const res = await axios.post('/api/upload', formData, {
    headers: {
      'Content-Type': 'multipart/form-data'
    }
})

然而现代的 API 大多是 json 接口,也可以单独把上传作为一个接口并返回上传后的路径。提交 表单时可在对应的 API 的接口中附件的字段填上这个路径就好了。

const res = await axios.post('/api/upload', file, {
    headers: {
      'Content-Type': file.type
    }
})

Auth

Your can use interceptors to ask for a new access token when the old one is expiring.

import axios from 'axios'

service.interceptors.response.use(
  response => {
    if (response.data.code === 409) {
        return refreshToken({
              refreshToken: localStorage.getItem('refreshToken'),
              token: getToken()
          }).then(res => {
              const { token } = res.data
              setToken(token)
              response.headers.Authorization = `${token}`
            }).catch(err => {
              removeToken()
              router.push('/login')
              return Promise.reject(err)
            }
          )
    }
    return response && response.data
  },
  (error) => {
    Message.error(error.response.data.msg)
    return Promise.reject(error)
  }
)

References

  1. https://stackoverflow.com/questions/4083702/posting-a-file-and-associated-data-to-a-restful-webservice-preferably-as-json
  2. https://stackoverflow.com/questions/43013858/how-to-post-a-file-from-a-form-with-axios
  3. https://stackoverflow.com/questions/12989442/uploading-multiple-files-using-formdata
  4. https://github.com/axios/axios/issues/1139#issuecomment-459728126
  5. https://mp.weixin.qq.com/s/zVCFUYKtVv0MeKMkjOb6xw
WeChat Qr Code

© 2016-2022 Yifei Kong. Powered by ynotes

All contents are under the CC-BY-NC-SA license, if not otherwise specified.

Opinions expressed here are solely my own and do not express the views or opinions of my employer.

友情链接: MySQL 教程站