美文网首页
跨域的解决方式

跨域的解决方式

作者: 阿鲁提尔 | 来源:发表于2017-09-21 20:26 被阅读0次

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()

相关文章

  • springboot 在整合shiro后,跨域就失效了。

    原springboot 解决跨域问题 使用 tomcat 中的 Filter的方式解决跨域

  • 跨域

    ??JSONP只能解决GET请求跨域,不能解决POST请求跨域问题,XHR2可以解决GET,POST方式的请求跨域...

  • AJAX

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

  • Vue实现跨域请求

    一般解决跨域问题可以通过CORS跨域、JSONP和反向代理跨域。下面分别介绍这三种跨域方式: 1、CORS 以ne...

  • SpringBoot 实现前后端分离的跨域访问(CORS)

    springBoot小白写博客时遇到了跨域问题,顺便记录一下踩过的坑 springboot解决跨域的几种方式 方式...

  • Flask-cors跨域

    什么是跨域 为什么要考虑跨域问题 同源策略 解决跨域问题 方式一: 使用 JSONP (一种非Ajax技术,需要前...

  • 跨域解决方式

    出于安全方面的考虑,浏览器遵从同源策略的原则。即同协议(http/https)、同域名(jianshu.com/j...

  • 跨域解决方式

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

  • 跨域 & 跨域的几种解决方式

    什么是跨域 跨域是由于浏览器同源策略的限制,它是对 JavaScript 的限制。浏览器不允许执行其他网站的脚本 ...

  • 浏览器跨域及其解决方案

    title: 浏览器跨域及其解决方案author: Maydate: 20220428 什么是跨域跨域的表现解决跨...

网友评论

      本文标题:跨域的解决方式

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