一、创建http实例
const http = axios.create({ // 请求超时时间设置为 30 秒,超过这个时间请求会被终止 timeout: 1000 * 30, // 允许跨域请求时携带凭证(如 Cookies) withCredentials: true, // 设置请求头的 Content-Type 为 application/json; charset=utf-8,表明请求体的格式是 JSON,并指定字符编码。 headers: { 'Content-Type': 'application/json; charset=utf-8' } })
headers: { 'Content-Type': 'application/json; charset=utf-8' }
设置了请求的内容类型,表明发送的数据格式为 JSON。这对于服务器理解请求体中的数据格式至关重要。
通过指定 charset=utf-8
,你还确保了字符编码正确,尤其是在处理非ASCII字符时。这可以避免因编码不匹配导致的数据解析错误。
如果没有加上 Content-Type: application/json; charset=utf-8
,服务器可能无法正确解析请求体中的数据。具体后果包括:
数据解析错误:服务器可能会将请求体当作默认的表单数据处理,从而导致数据无法被正确解析。
请求失败:一些 API 可能要求明确的
Content-Type
,如果未提供,可能返回错误响应,例如 400 Bad Request。字符编码问题:如果请求体包含非 ASCII 字符,服务器可能会使用默认的字符编码(通常是 ISO-8859-1),从而导致乱码或解析错误。
总之,明确设置 Content-Type
有助于确保数据在传输过程中的一致性和正确性。
二、配置请求拦截器
http.interceptors.request.use(config => { config.headers['token'] = Vue.cookie.get('token') // 请求头带上token return config }, error => { return Promise.reject(error) })
三、配置响应拦截器
http.interceptors.response.use(response => { if (response.data && response.data.code === 401) { // 401, token失效 clearLoginInfo() router.push({ name: 'login' }) } console.log('response',response); // 在这里查看响应信息 return response }, error => { return Promise.reject(error) })
console.log('response',response)的结果
四、请求地址处理
http.adornUrl = (actionName) => { // 非生产环境 && 开启代理, 接口前缀统一使用[/proxyApi/]前缀做代理拦截! return (process.env.NODE_ENV !== 'production' && process.env.OPEN_PROXY ? '/proxyApi/' : window.SITE_CONFIG.baseUrl) + actionName }
五、GET请求参数处理
/** * get请求参数处理 * @param {*} params 参数对象 * @param {*} openDefultParams 是否开启默认参数? */ http.adornParams = (params = {}, openDefultParams = true) => { var defaults = { 't': new Date().getTime() } return openDefultParams ? merge(defaults, params) : params }
添加时间戳 't': new Date().getTime()
的好处:
确保请求的唯一性,避免浏览器或服务器端的缓存影响
用于请求的跟踪和日志记录。服务器可以记录每次请求的时间戳,这对于分析请求频率、响应时间等性能指标非常有用
在一定程度上增加表单重复提交的难度
将时间戳等默认参数封装在函数内部,减少了代码冗余
六、POST请求参数处理
http.adornData = (data = {}, openDefultdata = true, contentType = 'json') => { var defaults = { 't': new Date().getTime() } data = openDefultdata ? merge(defaults, data) : data return contentType === 'json' ? JSON.stringify(data) : qs.stringify(data) }
函数根据 contentType
参数的值来决定如何格式化合并后的数据。如果 contentType
为 'json'
(默认值),则使用 JSON.stringify
方法将对象转换为JSON格式的字符串。如果 contentType
不是 'json'
,则假设是表单数据(application/x-www-form-urlencoded
或 multipart/form-data
),并使用 qs.stringify
方法(这里假设 qs
是一个查询字符串(query string)解析和字符串化库,如qs
npm包)将对象转换为查询字符串格式的字符串。
七、将http实例挂载全局
在vue项目的main.js中
import httpRequest from '@/utils/httpRequest' Vue.prototype.$http = httpRequest
八、使用get方法
async getMarketList() { this.$http({ url: this.$http.adornUrl('/xxx/xxx/xxxxxxxxx'), method: 'get' }).then(({ data }) => { if (data && data.code === 0) { this.marketList = data.data // console.log('this.marketList', this.marketList) } else { this.marketList = [] } }) },
九、使用post方法
// 提交表单 dataFormSubmit() { // console.log(Encrypt(this.dataForm.password)); this.$refs['dataForm'].validate((valid) => { if (valid) { this.$http({ url: this.$http.adornUrl('/xxxx/login'), method: 'post', data: this.$http.adornData({ 'username': this.dataForm.userName, 'password': Encrypt(this.dataForm.password), 'uuid': this.dataForm.uuid, 'captcha': this.dataForm.captcha }) }).then(({ data }) => { if (data && data.code === 0) { this.$cookie.set('token', data.token) this.$router.replace({ name: 'home' }) } else { this.getCaptcha() this.$message.error(data.msg) } }) } }) },