美文网首页
面试11:通讯类

面试11:通讯类

作者: 5d18ee6b5b1c | 来源:发表于2018-12-02 16:54 被阅读0次

    课程思维导图

    通讯类.png

    Q:什么是跨域通信?

    一个域下的文档或脚本试图去请求另一个域下的资源

    Q:什么是同源策略?

    1. 同源:协议、域名、端口
    2. 非同源的限制:
      1. cookie、localStorage、indexDB无法读取
      2. DOM无法获得
      3. Ajax 请求不能发送

    Q:前后端通信有哪些?

    1. Ajax : 同源下的通信方式
    2. WebSocket:不受同源策略限制
    3. CORS:支持跨域通信,也支持同源通信

    Q:如何创建创建Ajax?

    ```javascript
    // 完整版
    function ajax(opt) {
        if(!opt.url) return;
        var xhr = XMLHttpRequest
            ? new XMLHttpRequest()
            : new ActiveXObject('Microsoft.XMLHTTP');
         var data = opt.data,
             url = opt.url,
             type = opt.type.toUpperCase(),
             dataArr = [];
         for (var k in data) {
             dataArr.push(k + '=' + data[k]);
         }
         if (type === 'GET') {
             url = url + '?' + dataArr.join('&');
             xhr.open(type, url.replace(/\?$/g, ''), true);
             xhr.send();
         }
         if (type === 'POST') {
             xhr.open(type, url, true);
             xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
             xhr.send(dataArr.join('&'));
         }
         xhr.onload = function () {
             if (xhr.status === 200 || xhr.status === 304) {
                 var res;
                 if (opt.success && opt.success instanceof Function) {
                     res = xhr.responseText;
                     if (typeof res ==== 'string') {
                         res = JSON.parse(res);
                         opt.success.call(xhr, res);
                     }
                 }
             } else {
                 if (opt.error && opt.error instanceof Function) {
                     opt.error.call(xhr, res);
                 }
             }
         };
    }
    // 简易版,只考虑GET方式
    var xhr = new XMLHttpRequest();
    var url = '/test';
    xhr.open('GET', url, true);
    /**
     * 监听服务端跟客户端通信的过程和进度
     */
    xhr.onreadystatechange = function () {
        /**
         * 每当 readyState 改变时,就会触发 onreadystatechange 事件。
         * 4: 请求已完成,且响应已就绪
         */
        if (xhr.readyState === 4) {
            // 200 成功
            if (xhr.status === 200) {
                console.log(xhr);
            } else {
                console.log('error');
            }
        }
    }
    xhr.send();//发起客户端请求
    ```
    

    Q:跨域解决方案有哪些?

    方案1:document.domain:

    1. 场景:两个网页一级域名相同,只是二级域名不同
    2. 方案:浏览器允许通过设置document.domain共享 Cookie。这种方法只适用于 Cookie 和 iframe 窗口,LocalStorage 和 IndexDB 无法通过这种方法

    方案2:通过jsonp跨域

    ```javascript
    // 客户端实现:
    <script>
        var script = document.createElement('script');
        script.type = 'text/javascript';
     
        // 传参并指定回调执行函数为onBack
        script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';
        document.head.appendChild(script);
     
        // 回调执行函数
        function onBack(res) {
            alert(JSON.stringify(res));
        }
    </script>
    // 服务端(返回时即执行全局函数)
    onBack({"status": true, "user": "admin"})
    ```
    

    方案三:location.hash

    场景:当前页面 A 通过iframe或frame嵌入了跨域的页面 B

    ```javascript
    // 在A中伪代码如下:
    var B = document.getElementsByTagName('iframe');
    B.src = B.src + '#' + 'data';
    // 在B中的伪代码如下:
    window.onhashchange = function () {
      var data = window.location.hash;
    };
    ```
    

    方案四:postMessage

    HTML5引入跨文档通信API,这个API为window对象新增了一个window.postMessage方法,允许跨窗口通信,不论这两个窗口是否同源

    ```javascript
    // 例如,窗口A(http:A.com)向跨域的窗口B(http:B.com)发送信息
    var popup = window.open('http://B.com', 'title');
    popup.postMessage('Hello World!', 'http://B.com');
    // 在窗口B中监听
    window.addEventListener('message', function (event) {
          console.log(event.origin);    // 消息发向的网址
          console.log(event.source);    // 发送消息的窗口
          console.log(event.data);      // 消息内容
    }, false);
    ```
    

    方案五:WebSocket

    ```javascript
    var ws = new WebSocket('wss://echo.websocket.org');
    ws.onopen = function (evt) {
        console.log('Connection open ...');
        ws.send('Hello WebSockets!');
    };
    ws.onmessage = function (evt) {
        console.log('Received Message: ', evt.data);
        ws.close();
    };
    ws.onclose = function (evt) {
        console.log('Connection closed.');
    };
    ```
    

    方案六:CORS

    ```javascript
      fetch('/some/url/', {
          method: 'get',
      }).then(function (response) {
      }).catch(function (err) {
        // 出错了,等价于 then 的第二个参数,但这样更好用更直观
      });
    ```
    

    相关文章

      网友评论

          本文标题:面试11:通讯类

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