前端如何请求后台数据:结合代码,分享实用工具axios

本人是全栈IT工程师,如有开发方面的问题和需求,欢迎讨论交流。

前端页面展示的数据,归根到底,都是从数据库来的。

但是,前端应用是不能直接访问数据库的(例如:mysql)。

因为这样很不安全(数据库的用户名、密码可能会暴露,导致数据库信息被非法访问)。

因此,前端需要向后端发送请求,由后端把数据发给前端。在这其中,最常用的请求数据的工具就是:axios

1、基本使用

vue中使用axios,首先要安装 axiosvue-axios

指令如下:

npm install axios vue-axios

然后,在 main.js 文件中导入和注册 axios

代码如下:

import { createApp } from 'vue'
import VueAxios from 'vue-axios' //导入
import axios from 'axios' //导入
import AppAxios from './AppAxios.vue' 
const app = createApp(AppAxios)
app.use(VueAxios, axios) //注册
app.mount('#app')

接下来,在组件 AppAxios 中,使用一个button来发送axios get请求,并打印响应结果。




页面渲染如下:



可以看出,axios的用法并不复杂,最最核心的内容,无非就是:请求的url,请求方法,请求传参。

我们还可以通过配置项发送请求,如下所示:

// 发起一个post请求
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});

也可以通过别名,发送其它方法的请求。如下所示:

//别名发起请求
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.postForm(url[, data[, config]])
axios.putForm(url[, data[, config]])
axios.patchForm(url[, data[, config]])

再或者,可以构造一个axios实例。代码如下所示:

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

发送请求的方法如上所示,也都很好理解,此处就不再花时间啰嗦了。

2、config

在上一章节中,我们可以看到,axios请求函数的参数列表里,有个配置项config

它是什么呢?

从形式上来说,它是一个json结构的对象。

从用途来说,它对 axios 发送的请求数据,进行了配置。

(我们都知道,http协议有请求头)。

config对象有着非常丰富的参数,如下所示。

注:下面列出的参数虽然很多,但在实际使用中,最常用的,也就那么三、四个。其它配置项,都走的默认值。

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

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

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

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

    return data;
  }],

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

    return data;
  }],

  // 自定义请求头
  headers: {'X-Requested-With': 'XMLHttpRequest'},

  // `params` 是与请求一起发送的 URL 参数
  // 必须是一个简单对象或 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', 'DELETE 和 'PATCH' 请求方法
  // 在没有设置 `transformRequest` 时,则必须是以下类型之一:
  // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - 浏览器专属: FormData, File, Blob
  // - Node 专属: Stream, Buffer
  data: {
    firstName: 'Fred'
  },
  
  // 发送请求体数据的可选语法
  // 请求方式 post
  // 只有 value 会被发送,key 则不会
  data: 'Country=Brasil&City=Belo Horizonte',

  // `timeout` 指定请求超时的毫秒数。
  // 如果请求时间超过 `timeout` 的值,则请求会被中断
  timeout: 1000, // 默认值是 `0` (永不超时)

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

  // `adapter` 允许自定义处理请求,这使测试更加容易。
  // 返回一个 promise 并提供一个有效的响应 (参见 lib/adapters/README.md)。
  adapter: function (config) {
    /* ... */
  },

  // `auth` HTTP Basic Auth
  auth: {
    username: 'janedoe',
    password: 's00pers3cret'
  },

  // `responseType` 表示浏览器将要响应的数据类型
  // 选项包括: 'arraybuffer', 'document', 'json', 'text', 'stream'
  // 浏览器专属:'blob'
  responseType: 'json', // 默认值

  // `responseEncoding` 表示用于解码响应的编码 (Node.js 专属)
  // 注意:忽略 `responseType` 的值为 'stream',或者是客户端请求
  // Note: Ignored for `responseType` of 'stream' or client-side requests
  responseEncoding: 'utf8', // 默认值

  // `xsrfCookieName` 是 xsrf token 的值,被用作 cookie 的名称
  xsrfCookieName: 'XSRF-TOKEN', // 默认值

  // `xsrfHeaderName` 是带有 xsrf token 值的http 请求头名称
  xsrfHeaderName: 'X-XSRF-TOKEN', // 默认值

  // `onUploadProgress` 允许为上传处理进度事件
  // 浏览器专属
  onUploadProgress: function (progressEvent) {
    // 处理原生进度事件
  },

  // `onDownloadProgress` 允许为下载处理进度事件
  // 浏览器专属
  onDownloadProgress: function (progressEvent) {
    // 处理原生进度事件
  },

  // `maxContentLength` 定义了node.js中允许的HTTP响应内容的最大字节数
  maxContentLength: 2000,

  // `maxBodyLength`(仅Node)定义允许的http请求内容的最大字节数
  maxBodyLength: 2000,

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

  // `maxRedirects` 定义了在node.js中要遵循的最大重定向数。
  // 如果设置为0,则不会进行重定向
  maxRedirects: 5, // 默认值

  // `socketPath` 定义了在node.js中使用的UNIX套接字。
  // e.g. '/var/run/docker.sock' 发送请求到 docker 守护进程。
  // 只能指定 `socketPath` 或 `proxy` 。
  // 若都指定,这使用 `socketPath` 。
  socketPath: null, // default

  // `httpAgent` and `httpsAgent` define a custom agent to be used when performing http
  // and https requests, respectively, in node.js. This allows options to be added like
  // `keepAlive` that are not enabled by default.
  httpAgent: new http.Agent({ keepAlive: true }),
  httpsAgent: new https.Agent({ keepAlive: true }),

  // `proxy` 定义了代理服务器的主机名,端口和协议。
  // 您可以使用常规的`http_proxy` 和 `https_proxy` 环境变量。
  // 使用 `false` 可以禁用代理功能,同时环境变量也会被忽略。
  // `auth`表示应使用HTTP Basic auth连接到代理,并且提供凭据。
  // 这将设置一个 `Proxy-Authorization` 请求头,它会覆盖 `headers` 中已存在的自定义 `Proxy-Authorization` 请求头。
  // 如果代理服务器使用 HTTPS,则必须设置 protocol 为`https`
  proxy: {
    protocol: 'https',
    host: '127.0.0.1',
    port: 9000,
    auth: {
      username: 'mikeymike',
      password: 'rapunz3l'
    }
  },

  // see https://axios-http.com/zh/docs/cancellation
  cancelToken: new CancelToken(function (cancel) {
  }),

  // `decompress` indicates whether or not the response body should be decompressed 
  // automatically. If set to `true` will also remove the 'content-encoding' header 
  // from the responses objects of all decompressed responses
  // - Node only (XHR cannot turn off decompression)
  decompress: true // 默认值

}

3、响应结构

有请求,就会有响应。

axios响应结构,包含如下信息:

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

  // `status` 来自服务器响应的 HTTP 状态码
  status: 200,

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

  // `headers` 是服务器响应头
  // 所有的 header 名称都是小写,而且可以使用方括号语法访问
  // 例如: `response.headers['content-type']`
  headers: {},

  // `config` 是 `axios` 请求的配置信息
  config: {},

  // `request` 是生成此响应的请求
  // 在node.js中它是最后一个ClientRequest实例 (in redirects),
  // 在浏览器中则是 XMLHttpRequest 实例
  request: {}
}

结合代码演示的结果来看,确实如此。

代码和渲染结果如下:






4、拦截器

拦截器,个人觉得,叫它“过滤器”更为合适。

因为它的主要作用就是对数据进行检查。

通过了,就放行;没通过,就不再继续发送,而是进行错误处理。

它分为请求拦截器和响应拦截器。

请求拦截器,用在发送请求的时候,例如:对数据进行预处理,添加一个发送成功的特效,设置一个请求头auth等等。

响应拦截器,自然是用在处理响应的时候,例如:对错误响应进行统一处理,数据格式转换等。

  • 拦截器注册

注册方法,使用
axios.interceptors.request.use

axios.interceptors.response.use
函数进行注册。

这里模拟一个错误:将请求的url写成非法格式。

代码展示如下:




可以看出,在发送请求的时候,会有弹窗提示信息;在回复响应的时候,也有弹窗提示信息。

渲染结果如下:




  • 拦截器移除

移除拦截器,使用eject函数。

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

axios.interceptors.
request.eject(myInterceptor);

方法非常简单,这里就不再演示了。

5、axios封装

axios在项目中使用的时候,会进行封装。

封装就是将共性的东西抽象出来,封装到一个模块里。

然后,使用import导入。

这样在编写代码的时候,可以节约很多时间。

例如,将axios进行如下封装。

封装完之后,将axios对象export出去。

import axios from 'axios';

// 创建axios实例
const instance = axios.create({
    baseURL: 'http://localhost:3000', // 设置基础URL
    timeout: 5000 // 设置超时时间为5秒
});

// 请求拦截器
instance.interceptors.request.use(
    (config) => {
        // 设置默认请求头
        config.headers['Content-Type'] = 'application/json';
        const token = localStorage.getItem('token');
        if (token) {
            config.headers.Authorization = `Bearer ${token}`;
        }
        // 例如,这里可以添加对请求数据的预处理,如加密等
        // 如果有需要,可以在这里显示加载指示器,如showLoadingIndicator()
        return config;
    },
    (error) => {
        // 对请求错误进行处理
        console.error('请求拦截器错误:', error);
        return Promise.reject(error);
    }
);

// 响应拦截器
instance.interceptors.response.use(
    (response) => {
        // 例如,在这里可以隐藏加载指示器,如hideLoadingIndicator()
        // 可以对响应数据进行预处理,如提取核心数据等
        return response;
    },
    (error) => {
        // 统一错误处理
        if (error.response) {
            switch (error.response.status) {
                case 401:
                    // 未授权,跳转到登录页面
                    console.error('跳转到登录页面');
                    break;
                case 403:
                    // 权限不足提示
                    console.error('权限不足');
                    break;
                case 404:
                    console.error('资源未找到');
                    break;
                case 500:
                    console.error('服务器内部错误');
                    break;
                default:
                    console.error('其他错误状态码:', error.response.status);
            }
        } else if (error.code === 'ERR_NETWORK') {
            console.error('网络连接失败,请检查网络');
        } else {
            console.error('其他错误:', error);
        }
        return Promise.reject(error);
    }
);

export default instance;

使用的时候,import导入即可。代码如下:




渲染结果的正确样例和错误样例,均符合预期。

渲染结果如下:



以上就是axios工具的核心用法,感谢阅读。

原文链接:,转发请注明来源!