这是我参与8月更文挑战的第6天,活动详情查看: 8月更文挑战
前言
说解决办法前,肯定要先说一下跨域的概念。
跨域 由于浏览器的同源策略,为了防范跨站脚本的攻击,禁止客户端脚本对不同域下的文档或脚本进行跨站调用资源。
同源:协议+域名+端口 (看下图,侵删)
同源是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。
所以协议、域名、端口有其中一个不一样就算是跨域。
来对比下面这些地址是否跨域:原地址:https://www.baidu.com/
| 地址(what) | 是否跨域(is) | 为什么(why) |
|---|---|---|
http://www.baidu.com | 是 | 协议不一致 |
https://www.baidu.cn | 是 | 域名不一致 |
https://www.baidu2.com | 是 | 域名不一致 |
https://www.baidu.com:8888 | 是 | 端口不一致(百度端口多少我也不知道) |
https://www.baidu.com/index.html | 否 | 同源 |
在开发时你是否在控制台看见类似的提示:
No 'Access-Control-Allow-Origin' header...
这就是跨域了,那下面来说一下跨域的解决方案
常见跨域解决方案
1.vue开发环境的proxyTable
proxyTable 是 vue-cli 脚手架在开发模式下,为我们提供的一个跨域的代理中转服务器服务.基于 (http-proxy-middleware插件)。
proxyTable 就是webpack在开发环境给我们提供的一个代理服务器,(使用的是 http-proxy-middleware)。
配置:
2.CORS
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,
接口请求头详情
- 在服务端进行控制是否允许跨域,可自定义规则
- 支持各种请求方式
3.nginx反向代理
利用nginx反向代理把跨域为不跨域,支持各种请求方式。
反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。
4.通过JSONP来解决跨域
这是比较早的解决方案,我们的script标签的src还是img标签的src,或者说link标签的href他们没有被同源策略所限制。它就是通过通过 script 标签加载并执行其他的域的事件之类。
缺点:只支持 get 和 http 请求;在请求完毕后可以通过调用 callback 的方式返回结果,如果请求失败,不会返回状态码。
5.postMessage来解决跨域
html5引入的message的API可以更方便、有效、安全的解决这些难题。postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
postMessage(data,origin)方法接受两个参数
1.data:要传递的数据,html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化,在低版本IE中引用json2.js可以实现类似效果。
2.origin:字符串参数,指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,所以可以不写,这个参数是为了安全考虑,postMessage()方法只会将message传递给指定窗口,当然如果愿意也可以建参数设置为"*",这样可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。
6.nodejs中间件代理跨域
如果后端是用[node.js}(nodejs.cn/learn)写的,可以…
var express =require('express');
var proxy = require('http-proxy-middleware')
app.use('/',proxy({target:'https://www.baidu.com',changeOrigin:true}));
app.listen(3000);
7.WebSocket协议跨域
WebSocket 是一种网络通信协议。
更多解决方案
网上提供的其它跨域解决方案,这里就不说明了
小结
以上说了一下跨域的概念和常用一些解决跨域的方法。其实前面五种我还有接触,后面几个是搜索出来的,算作新学习的方法,但是缺少实践。
如果你还有补充或者说明的欢迎留言评论。
熟能生巧(Practice make perfect!)。