跨域的解决方式

JSONP

JSONPJSON with Padding)是资料格式JSON的一种“使用模式”,可以让网页从别的网域要资料。
由于同源策略,一般来说位于server1.example.com的网页无法与不是 server1.example.com的伺服器沟通,而HTML<script>元素是一个例外。利用 <script>元素的这个开放策略,网页可以得到从其他来源动态产生的JSON资料,而这种使用模式就是所谓的 JSONP。用JSONP抓到的资料并不是JSON,而是任意的JavaScript,用 JavaScript直译器执行而不是用JSON解析器解析。

index.html

 <div class="container">
        <ul class="news">
            <li>习近平:坚持中国特色社会主义社会治理之路</li>
            <li>在组织生活会上普通党员习近平说了啥  喜迎十九大</li>
            <li>重访习近平十八大以来国内考察地  《辉煌中国》</li>
        </ul>
        <button id="btn">换一组</button>
    </div>
<script>
    $('#btn').addEventListener('click',function(){
      // 为按钮添加点击事件
        var script = document.createElement('script');
      // 创建一个script标签
        script.src='http://localhost:8080/getNews?callback=appendHtml'
      // 为script标签设置地址
        document.head.appendChild(script)
      //在head里添加script标签
        document.head.removeChild(script)
      //移除head里的script标签
    })


    // 处理返回的数据appendHtml(["xxx","xxx","xxx"])
    function appendHtml(news){
        var html = ''
        for(var i = 0;i<news.length;i++){
            html += '<li>'+news[i]+'</li>'
            // 把后台传递过来的数据,拆开加在<li></li>内
        }
        $('.news').innerHTML = html;
        //把<ul class="news"></ul>中的内容替换为处理好的数据
    }
    function $(id){
        return document.querySelector(id)
    }
</script>

router.js

app.get('/getNews',function(req,res){
    var news = [
        "<strong>习近平:坚持中国特色社会主义社会治理之路</strong>",
        "在组织生活会上普通党员习近平说了啥  喜迎十九大",
        "重访习近平十八大以来国内考察地  《辉煌中国》",
        "李克强同李显龙会谈  张德江主持会议  刘云山访越",
        "大国网信安全护航  2017年国家网络安全宣传周",
        "侠客岛:李显龙时隔近4年为何“突然”访华?",
        "<strong>墨西哥地震致一学校教学楼倒塌 约百名学生失踪<stong>",
        "深圳一小学65名学生现身体不适 官方:已停用操场",
        "媒体:想知道中国海军有多强?仅需一个细节",
        "特朗普演讲:朝鲜半岛无核化是唯一可接受的未来",
        "外媒:中国高铁网络预示着“高流动性时代”的到来",
        "外国专家:北斗已超越欧盟、俄罗斯卫星导航系统"
    ]
    // 内容库

    var data = []
    for(var i = 0;i<3;i++){
        var index = parseInt(Math.random()*news.length)
        // parseInt取整,抽取内容库的随机数字
        data.push(news[index])
        // 把这条随机的新闻,传给data数组
        news.splice(index,1)
        //移除这条新闻,避免重复
    }

    var cb = req.query.callback;
    // 获取传递的callback值
    if(cb){
        res.send(cb+'('+JSON.stringify(data)+')');
    //JSON.stringify 将JavaScript的值转化为JSON
    //如果有callback的值,返回callback值+(["xxx","xxx","xxx"])
    }else{
        res.send(data);        
    //如果没有,返回["xxx","xxx","xxx"]
    }
})

CORS

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

例:http://a.jrg.com:8080网站向http://b.jrg.com:8080/getNews获取数据

html

    <div class="container">
        <ul class="news">
            <li>习近平:坚持中国特色社会主义社会治理之路</li>
            <li>在组织生活会上普通党员习近平说了啥  喜迎十九大</li>
            <li>重访习近平十八大以来国内考察地  《辉煌中国》</li>
        </ul>
        <button id="btn">换一组</button>
    </div>

script

    $('#btn').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) )
        }
    }
    })

    function appendHtml(news){
        var html = '';
        for(var i = 0;i<news.length;i++){
            html += '<li>'+news[i]+'</li>'        
        }
        $('.news').innerHTML = html;
    }
    
    function $(id){
        return document.querySelector(id);
    }

router.js

app.get('/getNews',function(req,res){
    var news = [
        "<strong>习近平:坚持中国特色社会主义社会治理之路</strong>",
        "在组织生活会上普通党员习近平说了啥  喜迎十九大",
        "重访习近平十八大以来国内考察地  《辉煌中国》",
        "李克强同李显龙会谈  张德江主持会议  刘云山访越",
        "大国网信安全护航  2017年国家网络安全宣传周",
        "侠客岛:李显龙时隔近4年为何“突然”访华?",
        "<strong>墨西哥地震致一学校教学楼倒塌 约百名学生失踪<stong>",
        "深圳一小学65名学生现身体不适 官方:已停用操场",
        "媒体:想知道中国海军有多强?仅需一个细节",
        "特朗普演讲:朝鲜半岛无核化是唯一可接受的未来",
        "外媒:中国高铁网络预示着“高流动性时代”的到来",
        "外国专家:北斗已超越欧盟、俄罗斯卫星导航系统"
    ]

    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")
    // 返回来自http://a.jrg.com:8080的数据请求

    //res.header("Access-Control-Allow-Origin","*")
    //返回所有网站的数据请求

    res.send(data);
})

降域


a.html

  <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>
  <script>
    document.querySelector('.main input').addEventListener('input',function(){
    //给当前窗口的input绑定一个输入事件
      window.frames[0].document.querySelector('input').value = this.value;
      //把当前输入input的值,赋给第一个frames的input的值
  })

    document.domain = "jrg.com"
    //降域
  </script>

b.html

  <input id="input" type="text" placeholder="http://b.jrg.com:8080/b.html">
  <script>
    document.querySelector('#input').addEventListener('input',function(){
    //获取页面上的input,添加输入事件
      window.parent.document.querySelector('input').value = this.value;
      //把当前frame的input的值,赋给父级页面的input的值
  })
  document.domain = "jrg.com"
  //降域
  </script>

postMessage

postMessage对于不同的域下,可以向他发送一个数据,如果对方接受认可这个数据,那就可以去使用,如果对象没有去监控这个数据,就没有任何作用。


a.html

  <div class="ct">
    <h1>postMessage</h1>
    <div class="main">
    <input type="text" placeholder="http://a.jrg.com:8080/a.html">
  <iframe src="http://b.jrg.com:8080/b.html" frameborder="0"></iframe>
  </div>
  <script>
    $('.main input').addEventListener('input',function(){
      window.frames[0].postMessage(this.value,"*");
    })

    window.addEventListener('message',function(e){
      $('.main input').value = e.data
    })

    function $(id){
      return document.querySelector(id)
    }
  </script>

b.html

  <input id="input" type="text" placeholder="http://b.jrg.com:8080/b.html">
  <script>
    $('#input').addEventListener('input',function(){
      window.parent.postMessage(this.value,"*")
    })

    window.addEventListener('message',function(e){
      $('#input').value = e.data
    })

    function $(id){
      return document.querySelector(id)
    }
  </script>

其他跨域方式

js中几种实用的跨域方法原理详解

用到的函数
  • JSON.stringify()方法将一个 JavaScript 值转换为一个 JSON 字符串,如果指定了一个 replacer 函数,则可以替换值,或者如果指定了一个 replacer 数组,可选地仅包括指定的属性。
  • parseInt() 函数可解析一个字符串,并返回一个整数。
  • JSON.parse()方法用于将一个 JSON 字符串转换为对象。

参考文章

JSON.stringify()
parseInt() 函数
JSON.parse()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 浏览器安全的基石是"同源政策"。所谓"同源"指的是"三个相同"。 协议相同 域名相同 端口相同 同源政策的目的,是...
    cce117b0a0ce阅读 284评论 0 1
  • 跨域有很多种方式,下面就简单说说跨域最常见的几种解决方式1、JSONPJSONP是服务器与客户端跨源通信的常用方法...
    小囧兔阅读 382评论 0 0
  • 1.JSONP(JSON with Padding)可用于解决主流浏览器的跨域数据访问的问题。由于Web 页面上调...
    大主教小豪阅读 241评论 0 0
  • 新年的钟声敲响了,2016年又TM的过去了。忙忙碌碌的这一年我收获了些什么呢?嗯……怎么感觉只有年龄和体重呢。那些...
    邱小猫阅读 3,927评论 3 2
  • 夜至深处,四处无声,碾转翻身无眠,仔细思来,原是前几夜打游戏睡的太晚,形成了坏习惯导致的。 想到坏习惯,那么这一...
    游鲫阅读 456评论 0 0