美文网首页
各种跨域实现

各种跨域实现

作者: leocz | 来源:发表于2017-08-15 02:08 被阅读0次

JSONP实现跨域

  • 原理: 网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
  • 具体实现方式:
    1. 定义数据处理函数fun
    2. 创建script标签,src的地址执行后端接口,最后加个参数callback=fun
    3. 服务端在收到请求后,解析参数,计算返还数据,输出 fun(data) 字符串。
    4. fun(data)会放到script标签做为js执行。此时会调用fun函数,将data做为参数。
前端代码   

此例是从http://localhost:8080发出请求,向http://127.0.0.1:8080请求数据,域名不同,明显属于跨域

$('.change').addEventListener('click', function(){
    var script = document.createElement('script');
    script.src = 'http://127.0.0.1:8080/getNews?callback=appendHtml';
    document.head.appendChild(script);
    document.head.removeChild(script);
  })
  function appendHtml(news){
    var html = '';
    for( var i=0; i<news.length; i++){
      html += '<li>' + news[i] + '</li>';
    }
    console.log(html);
    $('.news').innerHTML = html;
  }

后端代码

app.get('/getNews', function(req, res){

  var news = [
    "第11日前瞻:中国冲击4金 博尔特再战200米羽球",
    "正直播柴飚/洪炜出战 男双力争会师决赛",
    "女排将死磕巴西!郎平安排男陪练模仿对方核心",
    "没有中国选手和巨星的110米栏 我们还看吗?",
    "中英上演奥运金牌大战",
    "博彩赔率挺中国夺回第二纽约时报:中国因对手服禁药而丢失的奖牌最多",
    "最“出柜”奥运?同性之爱闪耀里约",
    "下跪拜谢与洪荒之力一样 都是真情流露"
  ]
  var data = [];
  for(var i=0; i<3; i++){
    var index = parseInt(Math.random()*news.length);
    data.push(news[index]);
    news.splice(index, 1);
  }


  var cb = req.query.callback;   // 获取回调函数
  if(cb){
    res.send(cb + '('+ JSON.stringify(data) + ')'); // 组成函数调用时形式的字符串
  }else{
    res.send(data);
  }
})

JSONP只能用get请求来实现,JSONP的优势在于支持老式浏览器

2.cors实现跨域

CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 ajax 跨域请求资源的方式,支持现代浏览器,IE支持10以上。 实现方式很简单,当你使用 XMLHttpRequest 发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin; 浏览器判断该相应头中是否包含 Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。
具体实现方式:

  1. 当使用 XMLHttpRequest 发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理
  2. 如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin
  3. 浏览器判断该相应头中是否包含 Origin 的值,包含则处理响应,我们成功拿到返回的数据。不包含则由于同源策略的限制,无视响应,我们无法拿到数据
前端代码

此例是从a.jrg.com发送ajax请求,向b.jrg.com请求数据

 $('.change').addEventListener('click', function(){
    var xhr = new XMLHttpRequest();
    xhr.open('get', 'http://b.jrg.com:8080/getNews', true);
    xhr.send();
    xhr.onreadystatechange = function(){
      if(xhr.readyState === 4 && xhr.status === 200){
        appendHtml( JSON.parse(xhr.responseText) )
      }
    }
    window.xhr = xhr
  })
  function appendHtml(news){
    var html = '';
    for( var i=0; i<news.length; i++){
      html += '<li>' + news[i] + '</li>';
    }
    console.log(html);
    $('.news').innerHTML = html;
  }
后台代码

app.get('/getNews', function(req, res){

  var news = [
    "第11日前瞻:中国冲击4金 博尔特再战200米羽球",
    "正直播柴飚/洪炜出战 男双力争会师决赛",
    "女排将死磕巴西!郎平安排男陪练模仿对方核心",
    "没有中国选手和巨星的110米栏 我们还看吗?",
    "中英上演奥运金牌大战",
    "博彩赔率挺中国夺回第二纽约时报:中国因对手服禁药而丢失的奖牌最多",
    "最“出柜”奥运?同性之爱闪耀里约",
    "下跪拜谢与洪荒之力一样 都是真情流露"
  ]
  var data = [];
  for(var i=0; i<3; i++){
    var index = parseInt(Math.random()*news.length);
    data.push(news[index]);
    news.splice(index, 1);
  }
  res.header("Access-Control-Allow-Origin", "http://a.jrg.com:8080"); //在响应的头部添加允许其请求的地址,浏览器在接受到响应后,两者的地址比较,相同则返回响应数据,跨域成功。不同则拦截返回的数据(就是不给你看)。
  //res.header("Access-Control-Allow-Origin", "*");    //*代表所有地址都是可行的
  res.send(data);
})

CORS支持所有类型的HTTP请求,但是只有现代浏览器和ie10以上的浏览器支持。

postMessage实现跨域

postMessage()是HTML5的一个API,使用这种方法最重要的就是发送消息和接受消息。在页面A中向页面B发送请求,然后在页面B中监听请求并获取A发送的数据,即可实现跨域。

页面A发送消息:调用postMessage API向目标窗口B 发送消息
window.postMessage(data, origin)
页面B接收消息:目标窗口B监听message事件
window.addEventListener('message',function (e) { console.log(e.origin,e.data) })
请看具体例子

页面a   a.jrg.com/a.html  像localhost:8080/b.html发送信息

<div class="ct">
  <h1>使用postMessage实现跨域</h1>
  <div class="main">
    <input type="text" placeholder="http://a.jrg.com:8080/a.html">
  </div>

  <iframe src="http://localhost:8080/b.html" frameborder="0" ></iframe>

</div>
<script>
//URL: http://a.jrg.com:8080/a.html
$('.main input').addEventListener('input', function(){
  window.frames[0].postMessage(this.value,'http://localhost:8080/b.html');   // 向http://localhost:8080/b.html发送信息
})
window.addEventListener('message',function(e) {   //监听message事件,接收信息并输入
    $('#input').value = e.data
});
postMessage跨域.png

4. 降域

此种方法需要主域相同且子域不同,有较大限制

页面a
<div class="ct">
  <h1>使用降域实现跨域</h1>
  <div class="main">
    <input type="text" placeholder="http://a.jrg.com:8080/a.html">
  </div>

  <iframe src="http://b.jrg.com:8080/b.html" frameborder="0" ></iframe>

</div>

document.querySelector('.main input').addEventListener('input', function(){
  console.log(this.value);
  window.frames[0].document.querySelector('input').value = this.value;
})
document.domain = "jrg.com"
页面b

document.domain = 'jrg.com';   把两个页面的domain设置成一样即可
降域.png

相关文章

  • 各种跨域实现

    JSONP实现跨域 原理: 网页通过添加一个 元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到...

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

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

  • node跨域访问数据

    node返回数据时,设置下面头部跨域实现跨域

  • 跨域问题总结

    跨域, 为什么需要跨域?跨域有什么不好?怎么实现跨域? 一、什么是跨域 只要协议、域名、端口有任何一个不同,都被当...

  • 跨域问题总结

    跨域, 为什么需要跨域?跨域有什么不好?怎么实现跨域? 一、什么是跨域 只要协议、域名、端口有任何一个不同,都被当...

  • 什么是跨域?跨域有几种实现形式:

    跨域指的是跨过同源策略,实现不同域之间进行数据交互的过程叫跨域。跨域的实现形式主要有JSONP方法、CORS方法、...

  • 跨域

    跨域指的是跨过同源策略,实现不同域之间进行数据交互的过程叫跨域。跨域的实现形式主要有JSONP方法、CORS方法、...

  • 浏览器跨域问题,教你手写实现jsonp跨域

    跨域概述为什么会有跨域跨域解决办法:1、jsonp;2、后台代理手写实现jsonp跨域(包括服务器端代码) 跨域问...

  • JavaScript - GET/POST及跨域方法

    xhr 原生方法请求 window fetch 方法 关于跨域 利用JSONP实现跨域调用 使用 CORS(跨域资...

  • vue-cli proxyTable配置

    前端的跨域转发 后端不需要配置,前端就可以实现跨域 proxyTable 的通常配置 这样就可以实现基本的跨域转发...

网友评论

      本文标题:各种跨域实现

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