常见的跨域技巧及其原理

在了解怎么跨域之前,我们先要理解为什么会产生跨域。

跨域产生的原因

浏览器存在同源策略,为了安全。所谓同源是指“协议+域名+端口”三者相同,缺一不可。

同源侧滤限制的内容有:

  1. Cookie、localStorage、IndexDB等存储型内容
  2. DOM节点
  3. ajax请求

有四个标签是允许加载跨域资源的

  1. <img>标签
  2. <script>标签
  3. <link>标签
  4. <iframe>标签

如何解决跨域

在了解跨域是怎么产生了以后,我们来看看如何解决这个问题。

1、jsonp

原理

jsonp就是利用了<script>标签可以跨域请求资源的特性,将一个callback回调函数名,以形如?callback=test的方式拼接在请求url的search参数里,再通过GET请求传递给服务端。服务端接收到请求并处理完成后,返回一个形如test(response)responseBody。这样,前端拿到响应结果后,就会执行test方法并拿到里面的结果。

代码实现

前端代码实现可以在我的github里找到。

优缺点

优点:兼容性好
缺点:仅支持GET方法,可能会遭受XSS攻击。

2、cors

浏览器会自动进行CORS通信,实现CORS的关键是服务端,只要服务端支持,就实现了跨域。

实现流程

服务端设置Acces-Control-Allow-Origin就可以开启CORS。该属性表示哪些域名可以访问资源,如果设置通配符,则表示所有网站都可以访问资源。

通过CORS来解决跨域的话,会在发送请求时出现两种情况,简单请求复杂请求

简单请求

只要同时满足以下两大条件,就属于简单请求。

  • 条件1:使用下列方法之一
    • GET
    • HEAD
    • POST
  • 条件二:Content-Type为下面三者之一
    • text/plain
    • multipart/form-data
    • application/x-www-form-urlencoded

复杂请求

不符合以上条件的请求就是复杂请求。复杂请求会在正式通信之前,发送一个OPTION请求,该请求的作用是预检。通过该请求,来判断服务器是否支持跨域请求。

3、postMessage

关于postMessage的可以看我的另一篇文章,《从iframe高度自适应了解postMessage》,这边不再过多介绍了。

4、websocket

websocket也是支持跨域的。

5、服务端处理

同源策略是浏览器的安全策略,所以,在服务端是不存在跨域问题的。因此,我们可以通过先请求同域下的服务器,服务器帮我们去请求原本直接请求会跨域的请求,然后将结果返回给前端。

这个服务端可以有多种实现方案,nodeNginx、甚至交给你们的后端都可以。

6、document.domain

该方式只能用于二级域名相同的情况下,比如a.test.comb.test.com。需要分别给两个页面添加document.domain = test.com,表示二级域名相同就可以实现跨域了。

7、通过img标签

前面也提到了,<img>标签可以跨域。因此,当我们需要上报一些信息而不用关心返回结果的时候,可以使用<img>标签来跨域请求。
该方法类似jsonp,将需要访问的url和参数拼接到img标签的url中,通过GET请求该图片,就可以实现跨域请求。

具体实现也可以参考我的github

优缺点

优点:兼容性好
缺点:仅支持GET方法,但是因为不会用到返回值,所以遭受XSS攻击的可能性比jsonp低

适用场景

打点上报之类的只需要请求,不需要用到返回值的场景。

坚持原创技术分享,您的支持将鼓励我继续创作!