美文网首页
跨域的实现方式

跨域的实现方式

作者: losspm | 来源:发表于2017-06-17 16:03 被阅读23次

什么是跨域

只要协议、域名、端口有任何一个不同,都被当作是不同的域,对于端口和协议的不同只能通过后端来解决。浏览器一般情况下一个页面不能访问另外一个页面的脚本信息。

跨域的实现方法

跨域的实现方法有如下几种

JSONP

JSONP是JSON padding的简写,是应用JSON的一种新方法,在web服务中非常流行,JSONP看起来和JSON差不多,只不过是被包含在函数中的JSON。类似下面这样

callback({"name": "Nicolas" })

JSON由两部分组成:回调函数和数据,回调函数是当页面响应的时候页面调用的数据。回调函数的名字一般在请求中指定的。而数据就是传入回调函数的JSON数据。比如
http://jrg.com/index.html?callback=handler
这里指定的回调函数名字就是handler()。
JSONP是通过动态<script>标签来使用的,使用时候可以为src属性指定一个跨域URL。<script>元素和<img>元素类似,都有能力不受限制从其他域中加载资料。又因为JSONP是有效的javascript代码,因此在加载完成之后,就会立即执行。比如下面例子

function handleResponse(response){
    console.log("You`re at IP address" + response.ip + ", which is in" 
                + response.city + ", " + response.region_name);
}

var script = document.createElement("script");
srcipt.src = "htt[://freegeoip.net/json/?callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);

这个例子通过查询地理位置定位服务来显示Ip和位置信息。
JSONP在开发人员中非常流行,主要原因是JSONP简单易用,与图像ping相比,它的优点在于可以直接访问相应文本,支持在浏览器与服务器之间的双向通信,但是它也有不足的地方。
不足的地方体现在两个方面,首先JSONP从其他域中加载代码执行,如果其他域不安全,很有可能在响应中夹带着恶意代码,而此时出了完全放弃JSONP调用之外,没有办法追究。其次要确定JSONP请求是否失败并不容易。虽然HTML5给<script>元素新增了一个onerror事件处理程序,但是目前没有得到任何浏览器的支持。为此,开发人员不得不使用计时器检测指定时间是否收到响应。
具体例子如下

//前端
<html>
<head>
<style>
.container{
  width: 900px;
  margin: 0 auto;
}
</style>
</head>
<body>
<div class = "container">
  <ul class = "news">
    <li>第11日前瞻:中国冲击4金 博尔特再战</li>
    <li>双力争会师决赛</li>
    <li>女排将死磕巴西</li>
  </ul>
  <button class ="switch">换一组</button>
</div>
</boyd>
<script>
 var btn = document.querySelector(".switch");
 var container = document.querySelector(".news")
 btn.addEventListener("click", function(){
    var script = document.createElement("script");
    script.src = 'http://localhost: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);
        container.innerHTML = html;
    }
 }

</script>
</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);
    }
})

CORS(cross-origin-resource-sharing)

CORS是cross-origin-resrouce-sharing的缩写,定义了在必须访问跨域资源时,浏览器与服务器之间如何沟通,CORS后面的思想是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求是成功还是失败。
比如一个简单的使用GET和POST发送的请求,它没有自定义头部,主体内容是text/plain。在发送请求的时候,必须给它附加一个额外的origin头部,其中包含请求页面的信息,以便服务器根据这个头部来决定是否给予响应。下面是origin头部的一个示例。

origin: http://www.jirengu.com

如果服务器认为这个请求可以接收,就在access-control-allow-origin头部中回发相同的源信息(如果是公共资源,可以回发"*")。例如

Access-Control-Allow-Origin:http://www.jirengu.com

如果没有这个头部,或者有这个头部但是源信息不匹配,浏览器就会驳回请求。正常情况下,浏览器会处理这个请求。请求和响应都不包含cookie信息。
具体例子如下

//前端
<html>
<head>
<style>
.container{
  width: 900px;
  margin: 0 auto;
}
</style>
</head>
<body>
<div class = "container">
  <ul class = "news">
    <li>第11日前瞻:中国冲击4金 博尔特再战</li>
    <li>双力争会师决赛</li>
    <li>女排将死磕巴西</li>
  </ul>
  <button class ="switch">换一组</button>
</div>
</boyd>
<script>
 var btn = document.querySelector(".switch");
 var container = document.querySelector(".news")
 btn.addEventListener('click', function(){
    var xhr = new XMLHttpRequest();
    xhr.open('get', 'http://localhost:8080/getNews', true);
    xhr.send();
    xhr.onreadystatechange = function(){
      if(xhr.readyState === 4 && xhr.status === 200){
        var result = JSON.parse(xhr.responseText);
        var html ='';
        for(var i = 0; i < result.length; i++){
          html += '<li>' + result[i] + '</li>';
          container.innerHTML = html;
        }
      }
    }
 })
</script>
</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(news[index], 1);
    }
    res.header("Access-Control-Allow-Origin", "*");
    res.send(data);
});

降域

//a部分
<html>
<style>
  .ct{
    width: 910px;
    margin: auto;
  }
  .main{
    float: left;
    width: 450px;
    height: 300px;
    border: 1px solid #ccc;
  }
  .main input{
    margin: 20px;
    width: 200px;
  }
  .iframe{
    float: right;
  }
  iframe{
    width: 450px;
    height: 300px;
    border: 1px dashed #ccc;
  }
</style>

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

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

</div>


<script>
  var ipt = document.querySelector('.main input');
  ipt.addEventListener('input', function(){
  window.frames[0].document.querySelector('input').value = this.value;
})
document.domain = "hello.com"
</script>
</html>
//b部分
<html>
<style>
    html,body{
        margin: 0;
    }
    input{
        margin: 20px;
        width: 200px;
    }
</style>

    <input id="input" type="text"  placeholder="http://localhost:8080/b.html">
<script>
// URL: http://b.jrg.com:8080/b.html
var ipt = document.querySelector('#input');
ipt.addEventListener('input', function(){
    window.parent.document.querySelector('input').value = this.value;
})
document.domain = 'hello.com';
</script>
</html>

相关文章

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

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

  • springboot 三种跨域处理方式

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

  • 实现前端跨域的几种方式

    1、jsonp跨域实现方式 server.js 2、CORS跨域实现方式 index.html server1.j...

  • PHP跨域问题

    使用iframe方式实现局部刷新,但是iframe不支持跨域 通过script方式,src属性可以实现跨域,但只能...

  • JSONP跨域

    JSONP原理及应用 之前的文章中简单介绍过前端可以实现的跨域方式,这次介绍一种更为常用的跨域方式,但这种跨域方式...

  • AJAX

    题目 手写一个ajax 跨域的常用实现方式 知识点 XMLHttpRequest 状态码 跨域:同源策略,跨域解决...

  • js跨域问题

    来源 javascript中实现跨域的方式总结 第一种方式:jsonp请求;jsonp的原理是利用 标签的跨域特性...

  • 跨域之三:降域 和 postMessage

    本节内容:实现跨域常用的两种方式 —— 降域 和 postMessage 零:跨域报错展示 在非同源情况下,操作 ...

  • ajax跨域--nginx反向代理

    用nginx反向代理实现跨域,是最简单的跨域方式。只需要修改nginx的配置即可解决跨域问题,支持所有浏览器,支持...

  • 跨域的实现方式

    什么是跨域 只要协议、域名、端口有任何一个不同,都被当作是不同的域,对于端口和协议的不同只能通过后端来解决。浏览器...

网友评论

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

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