【知识梳理】3.8通信类

1.同源策略及限制

:协议(http://)、域名(www.example.com)、端口(80)

同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。

目的:这是一个用于隔离潜在恶意文件的关键的安全机制。

限制范围:

  • Cookie、LocalStorage 和 IndexDB 无法读取;
  • DOM 无法获得;
  • AJAX 请求不能发送。

参考文档:浏览器同源政策及其规避方法

可以跨域的三个标签

  1. 6.跨域通信的几种方式

    • 1.JSONP

    原理:通过script标签的异步加载实现的;

    //JSONP
    
    //1.浏览器发送请求,告诉服务端callback的名称
    
    
    //2.服务器响应下发script内容,callback的名称作为函数名返回
    
    
    //代码实现
     /**
      * [function 在页面中注入js脚本]
      */
     util.createScript = function (url, charset) {
         var script = document.createElement('script');
         script.setAttribute('type', 'text/javascript');
         charset && script.setAttribute('charset', charset);
         script.setAttribute('src', url);
         script.async = true;
         return script;
     };
    //本地需要有以callback的名称创建函数
     util.jsonp = function (url, onsuccess, onerror, charset) {
         var callbackName = util.getName('tt_player');
         window[callbackName] = function () {
             if (onsuccess && util.isFunction(onsuccess)) {
                 onsuccess(arguments[0]);
             }
         };
         var script = util.createScript(url + '&callback=' + callbackName, charset);
         script.onload = script.onreadystatechange = function () {
             if (!script.readyState || /loaded|complete/.test(script.readyState)) {
                 script.onload = script.onreadystatechange = null;
                 // 移除该script的 DOM 对象
                 if (script.parentNode) {
                     script.parentNode.removeChild(script);
                 }
                 // 删除函数或变量
                 window[callbackName] = null;
             }
         };
         script.onerror = function () {
             if (onerror && util.isFunction(onerror)) {
                 onerror();
             }
         };
         document.getElementsByTagName('head')[0].appendChild(script);
     };
    
    • 2.Hash

    url地址中#后边的叫Hash,Hash变动页面不会刷新(Hash做跨域通信的基本原理);
    url地址中?后边的叫search,search变动页面会刷新页面,所以search不能做跨域通信。

          // hash
    
          // 场景:当前页面 A 通过iframe或frame嵌入了跨域的页面 B,要给跨域的 B 发送消息
    
          // 在A中伪代码如下:
          var B = document.getElementsByTagName('iframe');
          B.src = B.src + '#' + 'data';//通过JSON.stringify()转成字符串'data'
          // 在B中的伪代码如下
          window.onhashchange = function () {
              var data = window.location.hash;
          };
    • 3.postMessage

    H5中新增加的实现跨域通信的方式

          // postMessage
    
          // 场景:窗口A(http:A.com)向跨域的窗口B(http:B.com)发送信息
          Bwindow.postMessage('data', 'http://B.com');
          // 在窗口B中监听
          Awindow.addEventListener('message', function (event) {
              console.log(event.origin);//http://A.com
              console.log(event.source);//Awindow
              console.log(event.data);//data
          }, false);
    • 4.WebSocket
        // Websocket
    
        var ws = new WebSocket('wss://echo.websocket.org');//ws非加密,wss加密
    
        //发送消息onopen
          ws.onopen = function (evt) {
              console.log('Connection open ...');
              ws.send('Hello WebSockets!');
          };
        //接收消息onmessage
          ws.onmessage = function (evt) {
              console.log('Received Message: ', evt.data);
              ws.close();
          };
        //关闭连接
          ws.onclose = function (evt) {
              console.log('Connection closed.');
          };
    

    参考文档:WebSocket 教程

    • 5.CORS

    新的通信标准(通过新的API:fetch()实现CORS通信)。可以理解为:支持跨域通信的Ajax。当你在浏览器中发送一个ajax跨域请求时,浏览器会在http头中加入一个origin。如果只是一个普通的ajax,跨域时就会被浏览器拦截。

          // CORS
          
          // url(必选),options(可选)
          fetch('/some/url/', {
              method: 'get',
          }).then(function (response) {
            //then 回调
          }).catch(function (err) {
            // catch捕获错误;出错了,等价于 then 的第二个参数,但这样更好用更直观
          });

    参考文档:跨域资源共享 CORS 详解

    • 6.服务器端设置 http header
    //注意:不同后端语言的写法可能不一样
    
    //第二个参数填写允许跨域的域名城,不建议直接写"*"
    response.setHeader("Access-Control-Allow-Origin","http://a.com,http://b.com");
    response.setHeader("Access-Control-Allow-Headers", "X-Requested-With");
    response.addHeader("Access-Control-Allow-Methods","GET,POST,PUT,DELETE,OPTIONS");
    
    
    //接受跨域的cookie
    response.setHeader("Access-Control-Allow-Credentials", "true");

你可能感兴趣的:(通信)