跨域解决方案之CORS
什么情况表示遇到跨域请求
一般在前后端分离项目中,前端请求接口,浏览器控制台报如下错误
类似 No 'Access-Control-Allow-Origin' header 报错
为什么会有跨域请求
跨域请求产生的原因是:浏览器的同源策略
这是一个用于隔离潜在恶意文件的重要安全机制.一旦请求的资源不是同源那么即是跨域
什么样的请求是跨域请求
判断是否是跨域,本质是判断是否同源.如果两个页面的协议,端口(如果有指定) 和域名都相同,则两个页面具有相同的源
例如:请求页面是:
http://store.company.com/dir/page.html
目标URL | 结果 | 原因 |
---|---|---|
http://store.company.com/dir2/other.html |
成功 | 同源 |
http://store.company.com/dir/inner/another.html |
成功 | 同源 |
https://store.company.com/secure.html |
失败 | 不同协议 |
http://store.company.com:81/dir/etc.html |
失败 | 不同端口 |
http://news.company.com/dir/other.html |
失败 | 不同域名 |
如何解决跨域请求问题
Vue 开发环境下跨域问题
使用vue-cli 构建项目,开发环境下解决跨域问题
// config/index.js
module.exports = {
dev: {
proxyTable: {
// 代理所有以 api 开头的请求为 http://api.com
'/api': {
target: 'http://api.com', // 接口地址
changeOrigin: true,
pathRewrite: {
'^/api': '' //替换 /api 为 ''
}
}
}
}
}
- 请求url: /api/xxx/ 匹配以/api开头的请求
- 代理后的请求url: http 😕/api.com/xxx ( target + pathRewrite )
- pathRewrite 重写路径, /api替换为’’
vue-cli 使用的是 http-proxy-middleware 这个中间件,还有更多配置,例如支持WebSocket
{
// ...
ws: true
}
线上环境下跨域解决
- Nginx 反向代理
在生产环境下,上面的方法起不到作用了.这个时候就可以通过修改nginx的配置文件,加入代理 - 添加 Access-Control-Allow-* 响应头
由于跨域资源共享(CORS) 这种机制的存在,当请求资源方和所请求的资源在不同的域或者端口,此时就会产生跨域请求:
1 先发起一次预检请求,获知服务器是否允许跨域.请求Method 为OPTIONS
2 在接收的响应头中包含了 Access-Control-Allow-* 等几个响应头后,被允许了跨域请求,即发起正式的请求
预检请求允许跨域的响应头
Access-Control-Allow-Origin: * // * 表示允许任意地址,也可是具体域名http://foo.example
Access-Control-Allow-Methods: * // * 表示允许任意方法,也可是POST, GET, OPTIONS等方法
Access-Control-Allow-Headers:Token,Custom-Head // 允许这些自定义的请求头
Access-Control-Max-Age:600 // 返回结果可以用于缓存的最长时间,单位秒,返回-1表示禁用缓存(非必须)
解决方法:在响应OPTIONS请求的响应头中,增加上述允许跨域的特殊响应头
参考链接
vue-cli参考文档
http-proxy-middleware项目
MDN-CORS说明 阮一峰 CORS详解