文中代码部分来源于:https://blog.csdn.net/weixin_56947857/article/details/115908520
新建request.js,主要用于建立请求和响应拦截
import axios from 'axios'
import { Message, MessageBox } from 'element-ui'//请根据自己的情况自信修改
import store from '../store'
// 创建axios实例
const service = axios.create({
baseURL: process.env.BASE_API, // api 的 base_url
timeout: 50000 // 请求超时时间
})
// request拦截器
service.interceptors.request.use(
config => {
// config.headers['Content-Type'] = 'application/json'
if (store.getters.token) {
config.headers['Authorization'] = 'Bearer ' + store.getters.token
// 让每个请求携带自定义token 请根据实际情况自行修改
}
return config
},
error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
}
)
// response 拦截器
service.interceptors.response.use(
response => {
/**
* code为201-206的暂时定为正确 可结合自己业务进行修改
*/
const res = response
if (res.status < 200 || res.status > 299) {
Message({
message: res.statusText,
type: 'error',
duration: 5 * 1000
})
if (res.status === 401 || res.status === 403) {
MessageBox.confirm(
'你已被登出,可以取消继续留在该页面,或者重新登录',
'确定登出',
{
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}
).then(() => {
store.dispatch('oidc/signOutOidc');
})
}
return Promise.reject('error')
} else {
return response.data
}
},
error => {
if (error.response) {
Message({
message: error.response.data.error.details,
type: 'error',
duration: 5 * 1000
})
console.log('err' + error.response.data) // for debug
} else {
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
console.log('err' + error.message) // for debug
}
return Promise.reject(error)
}
)
export default service
新建api.js,用于封装各种类型的HTTP请求
顺便说说常见HTTP请求方式及其区别。
HTTP请求的方法:
- HTTP/1.1协议中共定义了八种方法(有时也叫“动作”),来表明Request-URL指定的资源不同的操作方式
- HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。
- HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法
请求类型 | 描述 | 其他特点 |
---|---|---|
GET | 向特定的资源发出请求 | 查看所有任务或根据ID查看一个任务 1)URL长度有限制,各个浏览器要求都不一样,IE最短(2083字符,中文字符的话只有2083/9=231) 2)会被浏览器主动缓存 3)参数直接暴露在URL上,所以不能用来传递敏感信息 4)请求参数会被完整保留在浏览器历史记录里 |
POST | 向指定资源提交数据进行处理请求 | 新建一个任务,例如提交表单或者上传文件。数据被包含在请求体中。POST请求可能会导致新的资源的创建和/或已有资源的修改 1)URL长度没有限制 2)不会被浏览器缓存 3)请求参数不会被保存 |
PUT | 向指定资源位置上传其最新内容 | 更新任务,其他特征和POST类似 |
DELETE | 请求服务器删除 Request-URI 所标识的资源 | 删除任务 |
OPTIONS | 查询Web服务器的性能 | 由浏览器自动发起,目的就是去服务器检查一下接下来要到用的方法(GET、POST、PUT、detele)在服务器上是否支持。发起条件: 1) 跨域调用; 2)自定义头部; 3)请求头application/x-www-form-urlencoded、multipart/form-data、text/plain之外的格式 |
HEAD | 跟GET一样,只是仅返回头部信息,不返回消息体 | 常用来测试链接的有效性,可达性,以及最近的修改信息 |
TRACE | 回显服务器收到的请求 | 主要用于测试或诊断 |
CONNECT | HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器 |
虽然 HTTP 的请求方式有 8 种,但是我们在实际应用中常用的也就是 get 和 post,其他请求方式也都可以通过这两种方式间接的来实现。
api.js示例代码
import request from "@/utils/request"; //引入上面封装好的request.js
import qs from 'qs' //qs是一个增加了一些安全性的查询字符串解析和序列化字符串的库。npm install qs
// get请求方式
export function getConsumeByPhone(query) {
return request({
url: `/v1_consume/getConsumeByPhone`,
method: "get",
params: query
});
}
// post请求方式
export function addLeaveMessage(query) {
return request({
url: `/v2_leave/addLeaveMessage`,
method: "post",
data: qs.stringify(query),
});
}
//delete请求方式
export function deleteByIdCard(id) {
return request({
url: `/card/deleteById/${id.id}/${id.updater}`,
method: "delete"
});
}
//下面说说data数据上传
//当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串
(name1=value1&name2=value2…),然后把这个字串append到url后面,用?分割,加载这个
新的url。
export function getOpenId(query) {
return request({
url: `/v1_auth/getOpenId`,
method: "post",
data: qs.stringify(query),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
}
// data上传2
export function getCode(query) {
return request({
headers: {
'Content-Type': 'application/json'
},
url: `/v1_global/getCode`,
method: "post",
data: qs.stringify(query),
});
}
// **当action为post时候,浏览器把form数据封装到http body中,然后发送到server。
如果没有type=file的控件,用默认的application/x-www-form-urlencoded就可以了。
但是如果有type=file的话,就要用到multipart/form-data了。浏览器会把整个表单以控件
为单位分割,并为每个部分加上Content-Disposition(form-data或者file),Content-Type
(默认为text/plain),name(控件name)等信息,并加上分割符(boundary)。**
export function upload(query) {
return request({
headers: {
'Content-Type': 'multipart/form-data'
},
url: `v1_global/upload`,
method: "post",
data: query
});
}
// data上传4
export function uploadFace(query) {
return request({
headers: {
'Content-Type': 'applic/v1_pFace/uploadFace'
},
url: `/v1_pFace/uploadFace`,
method: "post",
data: query
});
}
使用时直接引入即可,vue写法参照 import { uploadFace } from '@/api/api'
qs的作用
POST提交数据有两种数据传输方式,FormData和payload,这两种方式浏览器是通过Content-Type来进行区分:
Payload Content-Type: 'application/json; charset=utf-8'
Form Data Content-Type: 'application/x-www-form-urlencoded'
axios默认的content-type是application/json,传输的样式是
{
name:'小明',
age:'29'
}
如果使用的qs进行序列化,(注:qs.stringify()将对象序列化成URL的形式,以&进行拼接。安装axios即可使用qs。)那么content-type就是application/x-www-form-urlencoded,也就是常说的表单提交,传输的样式是FormData
name:'小明',
age:'29'
后台urlencoding后是
name='小明'&age='29'
对比下JSON.stringify。JSON是正常类型的JSON,
var a = {name:'hehe',age:10};
qs.stringify(a)
// 'name=hehe&age=10'
JSON.stringify(a)
// '{"name":"hehe","age":10}'
是否需要用qs去序列化参数完全取决于后端要怎么接受数据。
实例:
var qs = require("qs");
export const AxiosPost = (url, params) => {
return axios.post(url,qs.stringify(params), {
headers: {"Content-Type": "application/x-www-form-urlencoded" }
})
}
post需要用qs.stringify而get请求时不用
原因:HTTP请求中的get请求和post请求参数的存放位置是不一样的,get请求的参数以键值对的方式跟在url后面的,而post请求的参数是以键值对的方式在请求体里的,用Qs.stringify()就是把传入的对象转换为键值对。