跨域的几种实现方式

作者: fanlelee | 来源:发表于2019-05-24 13:11 被阅读87次

一、背景

同源策略

同源策略可以理解为浏览器的一种安全机制,浏览器只允许与本域下的接口进行交互。不同源的客户端在没有明确授权的情况下,不能读写服务端的资源。

什么是不同源呢:
补充点

在出现跨域问题时,浏览器究竟在哪一步进行了拦截?客户端请求时?服务器不做出响应?还是服务器响应后浏览器拒绝的响应??


image.png
image.png

测试发现,在客户端和服务端不同源的情况下,服务端其实是有响应的,在此时是浏览器的同源策略拒绝了响应,认为这样不安全。

二、解决跨域问题

1. JSONP(JSON with Padding)

  • 原理: 在HTML中用script标签在加载其他域下的js,那么JSON就是利用这一特性来请求服务端,从而避免了ajax请求出现的跨域问题
  • 具体实施
    1. 定义数据处理函数_fun
    2. 创建script标签,并添加src地址来请求服务端接口,在src尾端加上自定义参数callback=_fun
    3. 服务端收到请求后,根据get参数判断返回拼接的字符串:'_fun(data)'
    4. _fun(data)会放到script标签作为js执行,那么此时就会调用_fun函数,将data作为函数的参数
  • 相应代码
    客户端:
<body>
    <button class="btn">获取天气</button>
</body>
<script>
    function weather(data){
        console.log(data)
    }
    document.querySelector('.btn').addEventListener('click', function(){
        var script = document.createElement('script')
        script.src = 'http://localhost:8080/getWeather?callback=weather&a=b'
        document.head.appendChild(script)
        document.head.removeChild(script)
    })
</script>

服务端:

    '/getWeather':function(req, resp){
        resp.writeHead(200, 'success')
        if(req.query.callback){
            var res = JSON.stringify({'beijing':'sunny'})
            resp.end(req.query.callback+'('+res+')')
        }else{
            resp.end(JSON.stringify({'beijing':'rain'}))
        }
    }

2. CORS(Cross-Origin Resource Sharing)跨域资源共享

CORS,跨域资源共享,是一种ajax跨域请求资源的方式。(几乎所有浏览器都支持,但是ie必须10以上。)

  1. 当客户端使用XMLHttpRequest发送请求时,浏览器发现请求不符合同源策略,会加上一个请求头:origin;
<body>
    <button class="btn">获取天气</button>
</body>
<script>
    document.querySelector('.btn').addEventListener('click', function(){
        var xhr = new XMLHttpRequest()
        xhr.open('get', 'http://www.b.com:8080/getWeather', true)
        xhr.onload = function(){
            
            console.log(xhr.responseText)
        }
        xhr.send()
    })
</script>
image.png
  1. 在服务端收到请求并响应时,设置在响应结果加上Access-Control-Allow-Origin;
    '/getWeather':function(req, resp){
        resp.setHeader('Access-Control-Allow-Origin','http://www.a.com:8080')
        resp.writeHead(200, 'success')
        resp.end(JSON.stringify({'beijing':'rain'}))
    }
image.png
或者response.setHeader('Access-Control-Allow-Origin','*'),‘*’代表接收所有地址的请求。
  1. 此时浏览器判断如果该响应头包含请求头origin的值,就接收响应,否则拒绝就拿不到响应数据。
    CORS与JSONP区别:
    1. CORS与JSONP的使用目的相同,但是比JSONP更强大;
    2. JSONP只支持GET请求,CORS支持所有类型的HTTP请求;
    3. JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。

3. 降域

会发现当页面嵌入iframe的时候,在不同源的二级域名情况下我们是不能通过js操作iframe里面的内容的,这时可以通过降域达到目的。

<body cz-shortcut-listen="true"><div class="ct">
  <h1>使用降域实现跨域</h1>
  <div class="main">
    <input type="text" placeholder="http://a.test.com:8080/a.html">
  </div>
  <iframe src="http://b.test.com:8080/b.html" frameborder="0"></iframe>
</div>
<script>
//URL: http://a.test.com:8080/a.html
document.querySelector('.main input').addEventListener('input', function(){
  console.log(this.value);
  window.frames[0].document.querySelector('input').value = this.value;
})
document.domain = "test.com"
</script>
</body>

4. postMassage

在某些情况下iframe里面的服务端是愿意提供一些接口的,这时就用到了postMessage(),postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。

//URL:http://www.a.com:8080/a.html
window.frames[0].postMessage(data,'*')
//URL:http://www.b.com:8080/b.html
window.addEventListener('message',function(e){
    console.log(e.data)
})

5. 服务端中转跨域

如果对方服务器不提供跨域支持怎么办呢?这是可以自己搭建server请求中转(在服务端不存在同源策略限制)。
现在我有一个天气预报页面http://www.a.com,需要向http://www.weather.com接口获取天气数据,但是这个接口不支持JSONP和CORS跨域,那么可以这样做:

  1. 搭建服务器,创建一个获取天气的接口http://www.b.com
  2. 设置接口http://www.b.com的响应头Access-Control-Allow-Origin:http://www.a.com
  3. 页面http://www.a.comhttp://www.b.com发请求
  4. http://www.b.com收到请求后,向http://www.weather.com获取天气数据,然后将天气数据返回给http://www.a.com

相关文章

  • #hello,JS:15 同源策略 & 跨域(JSONP)

    跨域有几种常见的方式?你有没有跨域使用的经验? 方式: 使用jsonp实现跨域?使用cors实现跨域?浏览器另类的...

  • Ajax 请求和跨域

    跨域的几种方式: cors方式 cross-orign-resource-shareing(跨域)参考:http:...

  • 跨域的几种实现方式

    JSONP JSONP 是JSON with padding(填充式JSON 或参数式JSON)的简写;JSONP...

  • 跨域的几种实现方式

    概念1:同源策略 同源策略,Same-origin policy,浏览器处于安全考虑,只允许与本域下的接口交互。不...

  • 跨域的几种实现方式

    JSONP CORS 降域 对于页面中使用iframe嵌套另外的网站时,如果符合同源策略,就可以通过window....

  • 跨域的几种实现方式

    一、背景 同源策略 同源策略可以理解为浏览器的一种安全机制,浏览器只允许与本域下的接口进行交互。不同源的客户端在没...

  • 跨域的几种实现方式与原理

    在实际工作中,遇到前后端进行数据交互,经常会碰到请求跨域,今天就来探讨一下什么是跨域以及跨域的几种实现方式! 什么...

  • 跨域的几种演示

    几种跨域方式的代码演示 JSONP 优点: 它不像XMLHttpRequest 对象实现 Ajax 请求那样受到同...

  • 跨域问题

    通过XHR实现Ajax通信的一个主要限制,来源于跨域安全策略。解决跨域总结了几下几种方式:一、跨源资源共享(COR...

  • springboot 三种跨域处理方式

    springboot 三种跨域处理方式:1.通过Filter方式实现全局跨域2.通过Interceptor方式实现...

网友评论

    本文标题:跨域的几种实现方式

    本文链接:https://www.haomeiwen.com/subject/brrbzqtx.html