背景:第一次和另一位后端合作,使用vue开发前端,刚开始接口跨域了,我和后端说明后他配置好了,但我请求后仍显示跨域,没多想我想先用vue的代理在本地开发好了,结果最后上线一直跨域。具体解决可看结尾部分
一、vue代理配置
在vue.config.js文件下,配置代理
可以根据自己需要配置多个代理
module.exports = {
... // 省略
devServer: {
// 可以配置多个代理
proxy: {
'/Apis': {
target: 'https://**self.com/', // 你的接口域名,baseUrl
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
},
'/Public': {
target: 'https://**self.com/',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
},
'/tool': {
target: 'https://**self.com/',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
},
},
},
}
二、上线后跨域问题描述
我的情况:后端说已经配置了跨域,控制台仍然报跨域
排查:经过一系列排查,在开发这工具中查看“网络=>全部”发现每次请求的时候,都会有两次请求,每次请求前都会进行一次预请求,每次预请求都会得到一个403 Forbiden的结果,如下图:
当时找了很久实在不知道是什么问题,于是把接口放到其他项目中用未封装的axios直接去请求,发现并没有跨域!最终我回到了该项目中封装的axios,发现里面有一个自定义的请求头,而这一份封装好的axios是和上一个后端合作的时候用的我直接拿过来用了,然后想起来他之前的token是放在请求头中的(一般做法是会放请求头中),这下就通了,我把封装的axios中的自定义请求头也就是传输token的那个请求头去掉了,就解决了。
三、补充点
预请求
1、什么是预请求?
跨域请求资源时浏览器为确认请求来源的安全性,会在正式的请求之前做一次预校验请求,待服务器允许之后才能发送正式的请求,这个预校验请求就是options请求。
并不是每次跨域资源请求都会发送options请求,当跨域请求为简单请求的时就不会发送预校验请求,当跨域请求为复杂请求时才会发送预校验请求。
2、什么是简单请求?
请求方式只能是:GET、POST、HEAD。
HTTP请求头限制这几种字段:Accept、Accept-Language、Content-Language、Content-Type、Last-Event-ID。
Content-type只能取:application/x-www-form-urlencoded、multipart/form-data、text/plain。
如果不满足以上条件的就是复杂请求。
最后解决:
复杂请求时才会发送预请求,这次是请求头的问题,前端传给后端的请求头,需要后端允许才可以传,不允许的不能传,我传多了
启发:排查和解决问题的思维
其实当时看到预请求的时候,就应该重视它的定义,只有复杂请求的时候才会发送预请求,那肯定是请求头有问题了,主要当时只想怎么让这个预请求不要跨域,却没想到能否不要发送这个预请求,思维短路了,关键是后端还不是用的这个方式拿到token的我却传了,所以在一开始就要和后端商量好传输token的方式呀!