Flyinsky's Codes
3148 字
16 分钟
Vue3WithVite/Axios网络请求
2023-11-16

Axios网络请求#

:::tip Axios

Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。

可查阅的文档:官方文档中文文档

:::

简而言之,使用javascript书写ajax异步请求用于现代前后端请求会使代码量非常大,严重拖长开发周期,而且很容易出bug。Axios封装了许多函数便于我们直接调用向后端发出请求。当然,我们可以在Vue中进一步封装函数导出全局,最后我们只需要在请求时指定请求路径和提交的数据便能做到与后端的交互。

(1)安装Axios组件库#

:::danger 提示

如果你阅读了本博客中的Vite Vue 3 Starter并使用其中的快速起步项目,请跳过此步骤,起步项目中已集成并封装好Axios请求库和方法。

:::

我们可以直接使用Node.js中的npm或其他包管理器直接将Axios组件库添加至本地开发环境。

Using npm:

npm install axios

Using bower:

bower install axios

Using yarn:

yarn add axios

(2)配置Axios基本属性#

Axios的基本属性配置在src/main.js中书写。

// `main.js`
import axios from 'axios'
//**
	其他组件库引入信息
//
    
axios.defaults.baseURL = 'http://localhost:8080' 
//后端基础url 之后在请求时只用填写路径 Axios会自动以该url为基础添加路径
app.config.globalProperties.$axios = axios
//应用axios配置

(3)封装Axios方法#

即是Axios已经帮助我们封装好许多十分方便的请求函数,但在使用过程中还有许多参数需要填写。在实际使用过程中我们发现在使用post和get请求时我们重复书写了许多同样的属性,造成代码冗余。因此我们可以独立封装一个自定义的方法,节省重复书写的步骤,简化代码。

首先在src目录下新建目录net

在该目录下新建js文件index.js用于书写封装

—2024.8.30 更新

get可携带params请求 调用方式与post一致

InternalGet为不携带params请求版

//`src/net/index.js`
import axios from "axios";
import {ElMessage} from "element-plus";//引入用到的组件

const defaultError = () => ElMessage.error('发生错误,请联系管理员。') //定义默认错误提示语
const defaultFailure = (message) => ElMessage.warning(message) //后端请求返回失败信息时将其打印
//post请求示例
function post(url, data, success, failure = defaultFailure, error = defaultError) {//导入请求路径url,请求数据data,以及失败和成功的操作
    axios.post(url, data, { //使用axios的post请求 传入路径和数据
        headers: {
            "Content-Type": "application/x-www-form-urlencoded" //设置内容类型
        },
        withCredentials: true
    }).then(({data}) => {
        if (data.success)
            success(data.message, data.status) //判断数据内含的请求成功或失败并做出对应前端操作,执行的操作在组件中引用时书写
        else
            failure(data.message, data.status)
    }).catch(error)
}

function get(url, data = null, success, failure = defaultFailure, error = defaultError) {
    const config = {
        withCredentials: true,
        params: data  // 将数据作为查询参数
    };

    axios.get(url, config)
        .then(({data}) => {
            if (data.success)
                success(data.message, data.status)
            else
                failure(data.message, data.status)
        })
        .catch(error)
}

function InternalGet(url, success, failure = defaultFailure, error = defaultError) {
    axios.get(url, {
        withCredentials: true
    }).then((response) => {
        success(response.data);
    }).catch(error);
}


export {get, post, InternalGet} //导出get post InternalGet方法 供所有组件使用

完成上述步骤便封装好函数了,接下来在需要用到网络请求的组件中引入导出的函数直接使用即可

(4)Post和Get使用示例#

:::warning 注意

前端发送的请求方法必须与后端接口的请求方法一致,若出现前端请求后端接口请求方式不一致的情况会返回错误代码。

:::

1.POST#

:::tip POST

向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会建立新的资源或修改现有资源,或二者皆有。每次提交,表单的数据被浏览器用编码到HTTP请求的body里。浏览器发出的POST请求的body主要有两种格式,一种是application/x-www-form-urlencoded用来传输简单的数据,大概就是”key1=value1&key2=value2”这样的格式。另外一种是传文件,会采用multipart/form-data格式。采用后者是因为application/x-www-form-urlencoded的编码方式对于文件这种二进制的数据非常低效。

简单来说Post请求的使用情景为需要前端用户提交数据给后端,后端根据用户提交的数据返回结果。例如登录、注册、牛客提交运行代码等等。

:::

以下是一个登录post请求示例:

<script setup>
//引入post函数
import { post } from "@/net/index.js"; 
//定义登录数据表单 包括用户名、密码、是否记住登录状态    
const form = reactive({
  username: '',
  password: '',
  remember: false,
})
//定义登录函数
const login = () => {
  post('/api/auth/login', {
      username: form.username,
      password: form.password,
      remember: form.remember,
    }, (message) => {
      ElMessage.success(message)
    }, (message) => {
      ElMessage.warning('用户名或密码错误,请确认后重试!')
    }
  )
}
</script>

Post函数解读:

post('请求路径', {
      username: form.username,
      password: form.password,
      remember: form.remember,
    //该花括号中填写表单属性 格式如下:
    //后端接受属性名: 组件中定义的数据属性 
    }, (message) => {
      ElMessage.success(message)
    //该花括号中填写当后端返回成功状态执行的代码
    }, (message) => {
      ElMessage.warning('用户名或密码错误,请确认后重试!')
    //该花括号中填写当后端返回失败状态执行的代码 例如此处登录账密验证失败提示
    }
  )

2.GET#

:::tip GET

向指定的资源发出“显示”请求。使用GET方法应该只用在读取资料,而不应当被用于产生“副作用”的操作中,例如在网络应用程序中。其中一个原因是GET可能会被网络爬虫等随意访问。参见安全方法。浏览器直接发出的GET只能由一个url触发。GET上要在url之外带一些参数就只能依靠url上附带querystring。

简单来说,GET请求使用情景更倾向于只需要直接访问路径,不需要向后端提交任何路径,后端便会将对应数据返回至前端。

:::

以下是一个GET请求示例,情景为网页初始化时调用的向后端请求登录用户的个人信息:

getMyInfo() {
      InternalGet('/api/user/me', (data) => {
        this.user = data.message;
        console.log(data.message); // 在回调函数中输出日志
      });
}

InternalGet函数解读:

InternalGet('请求路径', (data) => {
    	//该花括号下填写拿到数据后执行的代码
        this.user = data.message;
        console.log(data.message); // 在回调函数中输出日志
});

(5).HTTP请求状态码#

当然,以下是HTTP状态码的中文释义:

  • 1xx 信息性状态码

    • 100 Continue:继续。服务器已接收请求的首部,并正在等待客户端发送请求主体。
    • 101 Switching Protocols:切换协议。服务器已根据客户端的请求切换协议。
    • 102 Processing:处理中。服务器正在处理请求,但尚未完成。
    • 103 Early Hints:早期提示。服务器可以开始发送响应的头部,以便客户端开始预加载资源。
  • 2xx 成功状态码

    • 200 OK:请求成功。客户端请求已成功。
    • 201 Created:已创建。成功请求并创建了新资源。
    • 202 Accepted:已接受。请求已被接受,但未完成。
    • 203 Non-Authoritative Information:非权威信息。服务器已成功处理请求,但信息不是原始的。
    • 204 No Content:无内容。服务器成功处理请求,但没有返回任何内容。
    • 205 Reset Content:重置内容。服务器成功处理请求,但要求客户端重置文档视图。
    • 206 Partial Content:部分内容。服务器成功处理了部分GET请求。
    • 207 Multi-Status:多状态。WebDAV高级集合的成员状态。
    • 208 Already Reported:已报告。WebDAV高级集合的成员已经在之前的操作中报告了状态。
    • 226 IM Used:IM使用。服务器已经完成了对资源的请求,并响应是一个或多个实例操作的实例。
  • 3xx 重定向状态码

    • 300 Multiple Choices:多种选择。请求的资源可用于多种形式。
    • 301 Moved Permanently:永久重定向。资源的URI已被更新。
    • 302 Found:找到。临时重定向。
    • 303 See Other:查看其他。请求者应当对不同的URI使用单独的GET请求来检索响应。
    • 304 Not Modified:未修改。客户端使用缓存的资源,未获取到新的内容。
    • 305 Use Proxy:使用代理。请求者只能使用代理访问请求的资源。
    • 307 Temporary Redirect:临时重定向。与302 Found相同,但要求客户端保持请求方法不变。
    • 308 Permanent Redirect:永久重定向。请求和所有将来的请求应该使用其他URI。
  • 4xx 客户端错误状态码

    • 400 Bad Request:请求错误。服务器不理解请求的语法。
    • 401 Unauthorized:未授权。请求要求身份验证。
    • 402 Payment Required:需要付款。保留供将来使用。
    • 403 Forbidden:禁止访问。服务器理解请求,但拒绝执行。
    • 404 Not Found:未找到。服务器找不到请求的资源。
    • 405 Method Not Allowed:方法不允许。请求中指定的方法不被允许。
    • 406 Not Acceptable:不可接受。服务器无法根据客户端请求的内容特性完成请求。
    • 407 Proxy Authentication Required:需要代理身份验证。与401类似,但指定了要访问的代理。
    • 408 Request Timeout:请求超时。服务器等待请求时发生超时。
    • 409 Conflict:冲突。由于请求中的冲突,请求无法被完成。
    • 410 Gone:已经不存在。请求的资源已不再可用。
    • 411 Length Required:需要长度。服务器拒绝在没有定义长度的情况下接受请求。
    • 412 Precondition Failed:先决条件失败。请求中指定的先决条件被服务器评估为失败。
    • 413 Payload Too Large:负载过大。请求的负载过大,服务器拒绝处理。
    • 414 URI Too Long:URI过长。请求的URI超过了服务器能够处理的长度。
    • 415 Unsupported Media Type:不支持的媒体类型。请求的格式不受请求页面的支持。
    • 416 Range Not Satisfiable:范围不符合要求。如果页面无法提供请求的范围,则返回此状态码。
    • 417 Expectation Failed:期望失败。服务器未满足”期望”请求标头字段的要求。
    • 418 I’m a teapot:我是一个茶壶。此请求要求服务器无法产生的茶壶。
    • 421 Misdirected Request:错误的请求。服务器无法产生适用于请求的响应。
    • 422 Unprocessable Entity:不可处理的实体。请求格式良好,但由于语义错误而无法遵循。
    • 423 Locked:被锁定。正在访问的资源被锁定。
    • 424 Failed Dependency:依赖失败。由于先前的请求失败,所以此请求失败。
    • 425 Too Early:太早。服务器不愿意冒险处理此请求。
    • 426 Upgrade Required:需要升级。客户端应切换到TLS/1.0。
    • 428 Precondition Required:要求先决条件。要求请求头中包含先决条件。
    • 429 Too Many Requests:请求过多。用户在给定的时间内发送了太多的请求。
    • 431 Request Header Fields Too Large:请求头字段太大。服务器不愿意处理请求,因为它的请求头字段太大。
    • 451 Unavailable For Legal Reasons:因法律原因不可用。该请求因法律原因不可用。
  • 5xx 服务器错误状态码

    • 504 Gateway Timeout:网关超时。充当网关或代理的服务器未及时从上游服务器收到请求。
    • 505 HTTP Version Not Supported:HTTP版本不支持。服务器不支持请求中所使用的HTTP协议版本。
    • 506 Variant Also Negotiates:变体协商。服务器内部配置错误,导致处理请求的资源时发生了递归。
    • 507 Insufficient Storage:存储不足。服务器无法存储完成请求所必须的内容。
    • 508 Loop Detected:检测到循环。服务器检测到无法完成请求的循环。
    • 510 Not Extended:未扩展。需要进一步处理请求才能完成。
    • 511 Network Authentication Required:要求网络身份验证。客户端需要进行身份验证才能获得网络访问权限。

    这是HTTP协议定义的所有状态码及其中文释义。不同的状态码用于描述请求或响应的处理状态,有助于进行有效的通信。如果您对特定状态码或情景有疑问,请告诉我,我将提供更详尽的解释。