vue axios跨域(CORS) Request Method: OPTIONS问题(预检请求)

我们在vue开发中用axios进行跨域请求时有时会遇到,同一个接口请求了两次,并且第一次都是options请求,然后才是post/get请求

options请求

get请求为什么会出现这种原因呢?

这是因为CORS跨域分为 简单跨域请求和复杂跨域请求;

简单跨域不会发送options请求,复杂跨域会发送一个预检请求options。

简单跨域满足的条件

1.请求方式是以下三种之一:

HEAD

GET

POST

2.HTTP的头信息不超出以下几种字段

Accept

Accept-Language

Content-Language

Last-Event-ID

Content-Type

但是Content-Type的值,只限于三个值:

application/x-www-form-urlencoded、multipart/form-data、text/plain

复杂跨域满足的条件

1.请求方法不是GET/HEAD/POST

2. post请求的Content-Type并非application/x-www-form-urlencoded, multipart/form-data, 或text/plain

3.请求设置了自定义的header字段

在header中自定义了字段就会触发options预检请求

// 请求拦截器

service.interceptors.request.use(

 config => {

 if (store.getters.token) {

 config.headers['Content-MD5'] = 'MD5'

 config.headers['authToken'] = getToken()

 config.headers['accessTokenRetireTime'] = getTokenTime()

 }



 return config

 },

 error => {

 console.log(error) // for debug

 return Promise.reject(error)

 }

)

解决方案

使用qs

1.可以通过跟后端协调,将所有options放行,此时便能通过post/get请求访问到数据。

2.引入qs模块处理数据

qs.parse()将URL解析成对象的形式

qs.stringify()将对象 序列化成URL的形式,以&进行拼接

1.安装qs

npm install qs

2.在main.js引入qs

import qs from 'qs';

Vue.prototype.$qs = qs;

3.vue实例组件里都可以直接用this.$qs.stringify(要处理的数据),进行数据转换

个人倾向第一种方法,如果用第二种方法对前后端来说比较繁琐。

//axios配置

import axios from 'axios'
import qs from 'qs'

// 添加响应拦截器
axios.interceptors.request.use(
	config => {
		if (config.method === 'post') {
			config.data = qs.stringify(config.data)
		}
		return config
	},
	error => {
		console.log(error)
		Promise.reject(error)
	}
)
这里我们看一下,其实就是在 axios 发起请求的前拦截请求,当请求类型是 post 的时候,把请求的入参数据 qs.stringify 一下,看一下前后数据格式的对比。

// qs.stringify 前
{
    "userId": "520b0ec329164dd9a4f216ba8d209029",
    "startTime": "1548950400000",
    "endTime": "1551369599999"
}
// qs.stringify 后
"userId=520b0ec329164dd9a4f216ba8d209029&startTime=1548950400000&endTime=1551369599999"
复制代码
这时候再去看后台我发起的请求, OPTIONS 已经不存在啦,只发起了一次正常的 post 请求

 使用Access-Control-Max-Age

这里说一个最简单的解决方法,只要后端同学在设置跨域请求数据的时候,添加 Access-Control-Max-Age ,这个参数的意思是把 OPTIONS 缓存起来,在指定的时间内,不会再次发起 OPTIONS 预请求,这样只有在第一次请求的时候会有 OPTIONS ,如果这个时间拉的足够长,其实并不太损耗资源,这算是一个迂回解决的方法。

// 后端设置,2592000单位秒,这里是30天
response.addHeader( "Access-Control-Max-Age", "2592000" )
复制代码
在控制台开启 Disable cache ,可以看到请求中还有 OPTIONS ,关闭 Disable cache 之后,再看请求已经没有了 OPTIONS

补充知识:vue当中axios调取后台数据 以及设置自定义请求头

从vue2.0开始vue-resource就不再维护了,尤大大开始推荐使用 axios。 具体详细教程可在官网查阅,这篇文章主要说明一些简单的问题。

第一步:安装axios

$ npm install axios

第二步:在 main.js中引入axios

第三步:设置我们自定义的 头请求;

header也可以在我们具体的请求中添加 header参数,我们这里是在main.js中添加公众的。

axios.defaults.timeout = 5000;

//请求超时的时间设定

axios.defaults.headers.post['Content-Type'] = 'application/json';

//axios默认的请求方式,可以自己设置

axios.defaults.baseURL = 'http://localhost:8008';

//axios默认的请求地址,开发时可以实际的接口地址来设置该值,去请求别人的接口(前提是后台已经帮你解决了接口的跨域问题,如果没有,我们自己可以代理转发解决开发跨域的问题)

axios.defaults.headers.common["token"] = "aaaaaaaaaaa";

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JackieDYH

谢谢您嘞!我会继续加油地

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值