通常我们在前端向后端请求数据的同时,需要做跨域申请,有时候没有做此操作,很容易出现报错,类似于Reason: CORS header ‘Access-Control-Allow-Origin’ missing此类的请求头问题,那么该如何解决,并且到底什么是跨域,请往下看。
1.什么是跨域
当一个url请求中协议、域名、端口中只要有任意一个与当前url不相同,即为跨域(可以想象当小雷在A面馆吃上一碗A套餐才算是同源,但凡不是小雷、不在A面馆、没点A套餐,只要其中一个不相同,皆不是同源)。
那么什么又是协议、域名、端口号呢?具体怎么判断,请看如下图。
本地url | 请求url | 跨域or同源 | 原因 |
http://www.kuayu.com | http://www.kuayu.com/app.html | 同源,直接访问 | 协议、端口、域名都相同 |
http://www.kuayu.com | https://www.kuayu.com | 跨域 | http≠https,协议不通过 |
http://www.kuayu.com | http://www.tongyuan.com | 跨域 | kuayu≠tongyuan,主域名不通过 |
http://www.kuayu.com | http://qq.kuayu.com | 跨域 | www≠qq,子域名不通过 |
http://www.kuayu.com:8080 | http://www.kuayu.com:8001 | 跨域 | 8080≠8001,端口号不通过 |
2.为什么会出现跨域
当我们了解到了什么是跨域后,就该知道为什么会出现跨域问题。
跨域的相反就是同源,同源策略是浏览器的一种自我保护机制,它是一种约定俗称的机制,在信息频繁交互的情况下,互相之间的安全隐私问题就是重中之重,所以同源就是为了保护自身安全尽量避免陌生url地址直接访问。
3.解决方案
1.JSONP
jsonp的原理就是利用<script>标签的跨域能力,也就是说<script>标签中的src属性是不受跨域影响的,就类如我们常用的<img src="图片url地址" alt="" />,就可以随时引用一些其他域名的图片供使用。
我们需要结合下述代码来实现
<script src="//i2.wp.com/www.example.com?callback=callFn"> function callFn(data){ console.log(data) }
优点:操作便捷,直接访问,适应性强
缺点:只支持get请求,且安全性低
2.CORS(推荐,仅需后端修改即可)
基本实现原理:CORS是一种基于HTTP头部的机制,通过在服务器端设置响应头部来允许跨域请求。浏览器会发送一个预检请求到目标服务器,目标服务器通过响应头部中的
在实际开发中,我们仅需要后端协助添加响应头参数即可,以下以node.js为例
app.use(function(req, res, next) { res.header("Access-Control-Allow-Origin", "http://example.com"); res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); res.header("Access-Control-Allow-Headers", "Content-Type"); next(); });
优点:CORS是一种标准化的跨域解决方案,易于实现和配置,支持各种HTTP请求方法,实际开发也是此方法居多
缺点:需要服务器端支持CORS,不适用于旧版本的浏览器
3.代理服务器
实现原理:通过在同一域名下设置代理服务器,将前端的跨域请求转发到目标服务器上,从而绕过浏览器的同源策略限制。
简单来说,就是因为同源策略是建立在客户端浏览器和服务器上的,但是服务器与服务器之间是不受同源策略影响,所以就可以直接访问响应。
当我们需要请求一个地址为“https://www.example.com/api/data/list”的后端数据的时候,可以在vue.config.js中配置一个代理服务器(如果没有需要自己在最外层目录新建一个vue.config.js文件)
原本是
getData(){ axios.get('https://www.example.com/api/data/list').then(res=>{ console.log(res) }) } // 此方法直接请求会导致跨域
现在按照如下配置vue.config.js
module.exports = { devServer:{ proxy:{ '/api':{ //表示会拦截以api为开头的请求 target:'https://www.example.com/api', //表示需要请求的目标url changeOrigin:true, // 是否开启跨域 pathRewrite:{ //重写路径 '^/api':'' //把/api开头的变为空 } } } } }
并且把原本的发送请求修改为如下
// 发送请求 getData(){ axios.get('api/data/list').then(res=>{ console.log(res) }) }
这样的话,请求就会先发送至代理服务器,然后通过代理服务器与目标服务器的交互,实现数据的传递。
优点:适用于所有浏览器,不需要服务器端额外配置。
缺点:需要额外的代理服务器配置和维护,增加了系统的复杂性。
以上就是目前主流的解决跨域问题(‘Access-Control-Allow-Origin’ missing)的常见方法,有其他疑问欢迎留言。