今天遇到的跨域问题, 本来想实现下 PDF 功能的, 然后安装了 vue-PDF 插件, 在功能调试的时候发现 No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. The response had HTTP status code 403 问题(localhost:8080 和 *.*.*.*:8080 虽然都指向本机, 但也属于跨域).
什么是同源策略
同源策略 / SOP(Same origin policy)是一种浏览器约定, 它是浏览器最核心也最基本的安全功能, 为了防止浏览器受到 XSS,CSFR 的攻击, 浏览器采用了同源策略 (保护 Cookie) 规定某域下的客户端在没明确授权的情况下不能读写另一个域的资源, 只有当 "协议 + 域名 + 端口" 三者相同都相同时才为同源.
什么是跨域
顾名思义就是一个网域向另一个网域进行资源交互, 即两个网域的 "协议 + 域名 + 端口" 不同. 跨域访问违反了同源策略, 所以当请求不在同一域名下的资源文件 ("协议 + 域名 + 端口") 时就报了 No 'Access-Control-Allow-Origin'错误.
Django 后台跨域问题解决
错误提示 No 'Access-Control-Allow-Origin'响应头, 我们就手动配置响应头 Access-Control-Allow-Origin, 之前用 Python 开发的时候有遇到过跨域问题: Django 实战 004: 跨域请求问题解决, 我们通过 corsheaders 中间件在后台进行了跨域设置允许所有 IP 访问.
Vue 前端跨域问题解决
除了可以在后台配置跨域问题, 其实在 vue 中也可以进行跨域配置的. vue cli30 修改配置信息需要新建 vue.config.JS 文件, 在 module.exports 方法的 devServer 对象中 proxy 选项来添加代理配置(当前端没有匹配到当前路由时就会被代理到服务器接口地址):
测试登录页面, 第一次打开前端路由时访问正常, 当我点击登录之后依旧提示: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 错误, 而且当我再次刷新路由的时候网页被代理到服务器接口地址.
查了下网上很多关于代理的配置方法我也试了下, 为代理添加了代理路径, 并为 axios 配置了 baseURL. 为了能跳回没有 API 的路径, 我通过 pathRewrite 属性对路由进行了重写, 但是还是出现了 No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 错误.
正确的跨域代理配置
单服务器请求配置
折腾了好久, 终于找到了正确的方式了, 比如说我们要通过 http://192.168.31.180:8080/login 访问后台接口 http://192.168.31.180:8000/login 实现登录功能. 设置代理之后代理会检查请求开头是否与代理映射相符, 不符合则不走代理, 所以使用 axios 请求的时候无需配置 axios.defaults.baseURL 属性(否则会跳过代理). 当匹配到映射路径时就会进入代理并将 target 属性补全到请求路径. 这种方式虽然成功了, 但是还是存在之前遇到的缺陷, 因为匹配的是'/',Vue 的路由也符合这一条件, 所以刷新后会进入代理配置直接跳转到后台路由了.
多服务器请求配置
当我们遇到要访问多个后台接口时, 我们可以为每个服务器配置不同代理服务, 以映射路径作为区分当我们访问到相应的路径时走对应的代理服务器, 但真实的请求中没有该路径, 所以我们需要利用 pathRewrite 属性把该路径去掉. 所以为了避免路由直接跳转至后台, 一个服务器接口也这种配置, 只有在请求接口的时候才走代理.
1, 路由请求中添加一个路由标识, 如:/API/login(切勿设置 axios.defaults.baseURL 属性)
2, 代理中映射路径指向标识路由, 当匹配到映射路径时就会进入代理并 target 属性补全到请求路径.
3, 利用 pathRewrite 属性重写路径, 还原真实的请求路由.
来源: http://www.jianshu.com/p/f4b89039ffd3