跨域的实现方式有哪些?

跨域的实现方式有很多种,比较典型的两种方式jsonp和CORS可以参考我之前的博客:
添加链接描述
参考:前端常见跨域解决方案(全)
前端各种跨域(上)
前端各种跨域(下)

什么是跨域?

狭义的跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的。

  1. 同源:协议+端口+域名三者相同
  2. 同源策略限制哪些行为?
    • Cookie LocalStorage和IndexDB无法读取
    • DOM 和JS对象无法获得
    • AJAX请求不能发送

跨域解决方案

  1. 通过jsonp跨域
  2. document.domain + iframe跨域
  3. location.hash + iframe跨域
  4. window.name + iframe跨域
  5. postMessage跨域
  6. 跨资源共享(CORS)
  7. nginx代理跨域
  8. nodejs中间件代理 跨域
  9. WebSocket协议跨域

1、jsonp

简单归纳:
因为<script>标签的src属性并不被同源策略所约束,可以获取任何服务器上脚本执行,所以jsonp的实现原理主要是利用<script>标签的src属性,局限性:只支持get方法

  1. 设定一个<script>标签
  2. 创建一个回调函数,允许用户传递这个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹JSON数据,完成回调
  3. 客户端接收到返回的js脚本,开始解析和执行

jsonp实现:参考:jsonp的原理与实现

简单实现:

function jsonp(req) {
  var script = document.createElement('script');
  var url = req.url + '?callback=' + req.callback.name;
  script.src = url;
  document.getElementsByName('head')[0].appendChild(script);
}
function hello(res) {
  console.log('hello' + res.data);
}

//  使用
jsonp({
  url: '',
  callback: hello
})

总结:Ajax(异步javascript和xml), 是一种可实现无需重新加载整个网页的情况下,能够更新部分网页的技术,其核心是通过XMR对象获取非本页内容 => 异步通信
而jsonp的核心则是动态添加
Ajax 和 jsonp的关联
  1. ajax和jsonp这两种技术在调用方式上“看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装
  2. ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加

2、document.domain + iframe跨域

实现原理:是两个页面都通过js强制设置document.domain为基础主域,就实现了同域。
局限性:仅限主域相同,子域不同的跨应用场景。

参考:
通过document.domain + iframe解决跨域问题

3、location.hash + iframe跨域

实现原理:a.html(属于A域) 和b.html(属于B域)想要通信,通过中间页c.html(属于A域)来实现。不同域之间利用iframe的location.hash来传值,(因为改变hash值不会导致页面刷新),相同域之间直接js访问来通信
a.html中创建一个iframe,其src指向b.html,向b.html传入hash值,b.html监听从a.html中传来的hash值,传给c.html(在b.html中创建iframe,其src指向c.html)

参考:iFrame跨域的方式
location.hash 实现跨域 iframe 自适应
优势:

  • 可以解决域名完全不同的跨域
  • 可以实现双向通讯

局限:

  • location.hash直接暴露在URL中
  • 由于URL大小的限制,数据容量和类型都有限

4、window.name + iframe跨域

5、postMessage跨域

postMessage是html5引入的API,可以更方便、有效、安全的解决这些问题。postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递,即,可解决:

  1. 页面和其打开的新窗口的数据传递
  2. 多窗口之间消息传递
  3. 页面与嵌套的iframe消息传递
  4. 上面三个场景的跨域数据传递

6、跨资源共享CORS

其原理主要是通过服务端在头部信里设置Access-Control-Allow-Origin即可,前端无需设置
若要带Cookie请求,需要前后端都进行设置,因为CORS请求默认不发送cookie和HTTP认证信息,若要把cookie发送到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段,另一方面,开发者必须在AJAX请求中打开withCredentials属性,否则,即使服务器同意发送Cookie,浏览器也不会发送。或者,服务器要求设置Cookie,浏览器也不会处理

  • 如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名
  • 由于同源策略的限制,所读取的Cookie为跨域请求接口所在域的cookie,而非当前页。只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。

局限:对于不支持CORS的浏览器无法使用该策略。

参考:CORS-阮一峰

7、nginx代理跨域

正向代理代理客户端(比如VPN),反向代理代理服务器
Nginx 是一个高性能的HTTP和反向代理web服务器其安装在目的主机端,主要用于转发客户机请求,后台有多个http服务器提供服务,nginx的功能就是把请求转发给后面的服务器,决定哪台目标主机来处理当前请求**
实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理domain2接口(nginx 反向代理模块 proxy_pass后面跟着一个 URL,用来将请求反向代理到 URL 参数指定的服务器上,),然后domain1访问nginx中的代理服务器,请求会被转发到domain2

server {
        listen       80;
        server_name  localhost;
        ## 用户访问 localhost,则反向代理到https://api.shanbay.com
        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass https://api.shanbay.com;
        }
}

参考:nginx反向代理
使用Nginx实现反向代理

8、Node.js中间件代理跨域

与nginx反向代理十分相似,只是将nginx代理服务器换成了Node服务器。

9、webSocket

webSocket本身不存在跨域问题,所以我们可以利用webSocket来进行非同源之间的通信
WebSocket 是一种通信协议,该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信,其请求头中有一个origin字段,正是因为有了Origin这个字段,所以 WebSocket 才没有实行同源政策。因为服务器可以根据这个字段,判断是否许可本次通信。如果该域名在白名单内,服务器就会做出如下回应。

猜你喜欢

转载自blog.csdn.net/weixin_43912756/article/details/108163274