美文网首页FE-study
跨域的几种演示

跨域的几种演示

作者: 饥人谷_bigJiao | 来源:发表于2018-03-20 00:41 被阅读0次

    几种跨域方式的代码演示

    JSONP

    优点:

    1. 它不像XMLHttpRequest 对象实现 Ajax 请求那样受到同源策略的限制
    2. 兼容性很好,在古老的浏览器也能很好的运行
    3. 不需要 XMLHttpRequest 或 ActiveX 的支持;并且在请求完毕后可以通过调用 callback 的方式回传结果。

    缺点:

    1. 它支持 GET 请求而不支持 POST 等其它类型的 HTTP 请求。
    2. 它只支持跨域 HTTP 请求这种情况,不能解决不同域的两个页面或 iframe 之间进行数据通信的问题
    3. 容易遭受XSS攻击,因为我们拿到的是对方接口的数据作为js执行,如果得到的是一个很危险js,获取了用户信息和cookies,这时执行了js就会出现安全问题。
    var http = require('http')
    var fs = require('fs')
    var path = require('path')
    var url = require('url')
    
    http.createServer(function(req, res){
      var pathObj = url.parse(req.url, true)
    
      switch (pathObj.pathname) {
        case '/getNews':
          var news = [
            "第11日前瞻:中国冲击4金 博尔特再战200米羽球",
            "正直播柴飚/洪炜出战 男双力争会师决赛",
            "女排将死磕巴西!郎平安排男陪练模仿对方核心"
            ]
          res.setHeader('Content-Type','text/json; charset=utf-8')
          if(pathObj.query.callback){
            res.end(pathObj.query.callback + '(' + JSON.stringify(news) + ')')  // 将数据处理后返回
          }else{
            res.end(JSON.stringify(news))
          }
    
          break;
    
        default:
          fs.readFile(path.join(__dirname, pathObj.pathname), function(e, data){
            if(e){
              res.writeHead(404, 'not found')
              res.end('<h1>404 Not Found</h1>')
            }else{
              res.end(data)
            }
          }) 
      }
    }).listen(8080)
    
    <!DOCTYPE html>
    <html>
    <body>
      <div class="container">
        <ul class="news">
        </ul>
        <button class="show">show news</button>
      </div>
    
    <script>
       // 通过script标签发送请求
      $('.show').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;
      }
    
      function $(id){
        return document.querySelector(id);
      }
    </script>
    
    </html>
    
    

    打开终端,输入 node server.js ,浏览器打开 http://localhost:8080/index.html

    CORS

    var http = require('http')
    var fs = require('fs')
    var path = require('path')
    var url = require('url')
    
    http.createServer(function(req, res){
      var pathObj = url.parse(req.url, true)
    
      switch (pathObj.pathname) {
        case '/getNews':
          var news = [
            "第11日前瞻:中国冲击4金 博尔特再战200米羽球",
            "正直播柴飚/洪炜出战 男双力争会师决赛",
            "女排将死磕巴西!郎平安排男陪练模仿对方核心"
            ]
          res.setHeader('Access-Control-Allow-Origin','*') // 设置响应头中的属性,允许所有的站点访问
          res.end(JSON.stringify(news))
    
          break;
    
        default:
          fs.readFile(path.join(__dirname, pathObj.pathname), function(e, data){
            if(e){
              res.writeHead(404, 'not found')
              res.end('<h1>404 Not Found</h1>')
            }else{
              res.end(data)
            }
          }) 
      }
    }).listen(8080)
    
    
    <!DOCTYPE html>
    <html>
    <body>
      <div class="container">
        <ul class="news">
        </ul>
        <button class="show">show news</button>
      </div>
    
    <script>
    
      $('.show').addEventListener('click', function(){
        xhr = new XMLHttpRequest();  // 创建 AJAX 请求
        xhr.open('GET','http://127.0.0.1:8080/getNews',true);
        xhr.send();
        xhr.onload = function(){
          appendHtml(JSON.parse(xhr.responseText));
        }
      })
    
      function appendHtml(news){
        var html = '';
        for( var i=0; i<news.length; i++){
          html += '<li>' + news[i] + '</li>';
        }
        console.log(html);
        $('.news').innerHTML = html;
      }
    
      function $(id){
        return document.querySelector(id);
      }
    </script>
    
    </html>
    

    启动终端,执行 node server.js ,浏览器打开 http://localhost:8080/index.html ,查看效果和网络请求

    postMessage

    HTML5为了解决这个问题,引入了一个全新的API:跨文档通信 API(Cross-document messaging)。
    这个API为window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源。
    举例来说,父窗口http://a.jrg.com向子窗口http://b.jrg.com发消息,调用postMessage方法可以了。
    postMessage方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源(origin),即"协议 + 域名 + 端口"。也可以设为*,表示不限制域名,向所有窗口发送

    • 首先创建 a.html
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title>postMessage</title>
    </head>
    <body>
      <iframe src="http://localhost:8080/b.html" ></iframe>
      <script>
        window.onload = function(){
          var targetOrigin = "http://localhost:8080";
          window.frames[0].postMessage('看到我发给你的信息没', targetOrigin);
        }
        window.addEventListener('message',function(e){
          console.log('a.html接收到信息:',e.data);
        });
      </script>
    </body>
    </html>
    
    • 创建 b.html
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <title>postMessageB</title>
    </head>
    <body>
      
      <script>
        window.addEventListener('message',function(e){
          if(e.source != window.parent){
            return
          }
          var data = e.data;
          console.log("b.html接收到的消息", data);
          parent.postMessage("我看到你发的消息了", e.origin)
        })
      </script>
    </body>
    </html>
    
    • 用http-server启动静态服务器,在浏览器中打开 http://localhos/a.html, 即可看到跨域成功

    相关文章

      网友评论

        本文标题:跨域的几种演示

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