使用工具: vue,axios
事情描述:
将token放进headers里面,在发送http请求时,会先发送options请求,再发送get请求。
产生的问题:
在react-native app中,部分ios的版本(目前得知是ios12会有此问题,ios13没有)会只发送options请求,然后就不发送get请求了,导致请求不到数据。
为什么先发送options请求,再发送get请求?
因为:将token放进headers里面了,http请求从简单请求变成了复杂请求。
解决思路:将复杂请求变成简单请求
(具体简单请求与复杂请求的区别请看这篇文章:https://www.jianshu.com/p/5cf82f092201)
简单来说需简单请求需要满足以下条件:
请求方法
GET,POST,HEAD不能自定义请求头header, 以下头部信息除外:
Accept,Accept-Language,Content-Language,Content-TypeContent-Type 的值仅限于下列三者之一:
text/plain
multipart/form-data 文件上传时要使用的数据类型
application/x-www-form-urlencoded 最常见的post的数据类型,也是表单提交的数据类型,jquery的ajax默认也是这个
开始解决问题:
方法一:(这个是网上大部分答案,但经实践此方法无效,你也可以试一下)
主要思路: 在request-headers中将Content-Type修改为application/x-www-form-urlencoded
请注意我的代码中对axios做了一层封装 请求分成了两部分,以方便管理接口
第一部分设置baseUrl
import axios from 'axios'
// axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
export function request(config) {
const instance = axios.create({
baseURL: "http:/0.0000.000.000"
})
//拦截请求
instance.interceptors.request.use(config => {
config.headers['Content-Type'] = 'application/x-www-form-urlencoded' //设置请求头Content-Type
if (config.method === 'get') { //☆☆☆此处意义见下文
// 给data赋值以绕过if判断
config.data = true
}
//取出保存的token并设置
let token = sessionStorage.getItem("token");
if (token) {
config.headers['token'] = token //设置请求头
}
return config
}, err => {
console.log(err)
})
//拦截响应
instance.interceptors.response.use(result => {
return result
}, err => {
console.log(err)
})
return instance(config)
}
第二部分设置config
import { request } from './request.js'
export function isVeried() {
return request({
method:"get",
url: "/laal/llll/lalala",
/* headers: { //也可以根据需要单独设置
'Content-Type': 'application/x-www-form-urlencoded'
}*/
})
}
第一部分代码中有一个标注了☆☆☆的地方,是如果不这样写,Content-Type是无法修改的,这是axios源码中的问题,当未设置requestData的时候axios会删掉Content-Type的设置,其这么做的原因在于是Get请求本身是不需要Content-Type的。
具体参考这篇文章:https://www.jianshu.com/p/998e248daf3b
修改完后成,发现,然并卵。
解决方法二:
不要在请求头中添加任何额外的东西!!不要把token放到headers里面!!!!!!!就不会变成复杂请求了!!!
请改为参数传给服务端,这样就不会有options请求了,问题迎刃而解。。。
import { request } from './request.js'
export function isVeried(token) {
return request({
method:"get",
url: "/lalala/hahaha/yeyeye",
params: {token}
})
}