Vue.js axios请求跨域解决
开发环境
前端VUE运行在本地:http://localhost:8088
后端API运行地址为http://www.imagemix.com
现在要通过axios调用后端接口,域名不同,浏览器依据同源策略,出现跨域问题.
原理
当我们在代码中写的 (get,post)请求跨域时, 浏览器在发出真正的请求前, 会自动的向服务端发出一个OPTIONS
预检请求, 然后浏览器通过分析服务端对OPTIONS
请求的响应头,来判断服务端是否支持跨域.
完整步骤
-
浏览器发出
跨域请求OPTIONS
请求
-
服务端收到请求,并做出响应
服务端返回的响应 -
浏览器分析服务端的响应信息,判断是否支持跨域.
浏览器检测结果
这次OPTIONS
请求服务端返回信息中没有Access-Control-Allow-Origin
字段,浏览器判定服务端不支持跨域, 于是后续请求不会执行
解决方法
如果服务端支持跨域, 那么服务端应该正确响应这个OPTIONS
请求,只要在返回的消息头中加上对应字段就行了
#在项目的入口文件里
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '*';
header('Access-Control-Allow-Origin:' . $origin);
header('Access-Control-Allow-Credentials:true');
header('Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers:Origin,Token, No-Cache, uniqid, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With');
header('Access-Control-Expose-Headers:uniqid');
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){
exit();
}
其他说明
-
Access-Control-Allow-Origin: *
表示允许哪个域名跨域访问 -
Access-Control-Allow-Headers:
允许浏览器跨域时携带的自定义头信息.
vue需要携带token,uniqid字段发送请求到服务器,在预检请求中需要告诉浏览器支持的字段,否则前端会报错 -
前后分离,导致生成的验证码无法通过cookie验证, 于是我在返回验证码图片的同时返回了一个自定义header表示验证码的唯一ID
uniqid = df2341f55fzz3vbd
, vue中需要记录这个值, 提交表单时再传上来.
需要加上header('Access-Control-Expose-Headers:uniqid');
vue才能取出这个自定义uniqid
var uniqid = response.headers.uniqid
另外记录axios携带header的方式
get请求
axios
.get(
process.env.BASE_API+'/index.php/Home/Index/Code',
{
responseType: 'arraybuffer',
headers:{
uniqid:_that.formData.headers.uniqid
}
})
.then(function(response){
console.log(response)
var contentType = response.headers['content-type']
var uniqid = response.headers.uniqid
sessionStorage.setItem('uniqid',uniqid)
console.log(uniqid)
var blob = new Blob([response.data],{type:contentType})
_that.formData.verify = URL.createObjectURL(blob)
})
},