通訊類

通訊類

javascript HTTP

1. 什麼是同源策略及限制:

  • 同源策略限制從一個源加載的文檔或腳本如何與來自另外一個源的資源進行交互。這是一個用於隔離潛在惡意文件的關鍵的安全機制。
    源:協議、域名、端口(默認 80)三個構成一個源。 不是一個源的文檔沒法去操做另外一個源的資源。
  • 限制:javascript

    - Cookie、LocalStorage 和 IndexDB 
    - Dom 沒法得到 
    - Ajax 不能發送

2. 先後端如何通訊:

  1. Ajax 同源下
  2. WebSocket 不限制
  3. CORS 支持跨源通訊 也支持同源通訊

3. 如何建立Ajax

XMLHttpRequest 對象的工做流程
兼容性處理(IE 瀏覽器的處理)
事件的觸發條件
事件的觸發順序
if(opt.url){
    // 聲明XMLHttpRequest 對象的工做流程
    var xhr = XMLHttpRequest ? new XMLHttpRequest () : new window.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 +'?' + dataArry.join('&');
        xhr.open(type,url.replace(/\?$/g,''),true);
        xhr.send();
    }
    if (type === 'POST') {
        xhr.open(type,url,true);
        xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
        xhr.send(dataArry.join('&'));
    }
    // 監聽它成功失敗
    xhr.onload = function () {
        // 200:304:重定向,利用本地緩存
        if (xhr.status === 200 || xhr.status === 304 ) { // 媒體資源加206
            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); 
                }
            }
        }
    }

4. 跨域通訊的幾種方式:

  1. JSONP
  2. Hash 「url 地址中 # 後面的東西是 Hash, Hash改變頁面不改變」「url 地址中 ?後面的東西是Search,Search 改變頁面刷新」
  3. postMessage「Html5 新增的,同源策略限制跨域通訊,但實際的開發業務中咱們又須要用到跨域通訊,因此出現這種方式」
  4. WebSocket「不受同源策略限制」
  5. CORS 「支持跨域通訊的 Ajax ,瀏覽器在識別你用Ajax發送跨域請求時,瀏覽器會在 HTTP 頭中加一個 Origin,若是沒有瀏覽器就會攔截」

代碼實例:

var util = {};

 /**
  * [function 在頁面中注入js腳本]
  * @param  {[type]} url     [description]
  * @param  {[type]} charset [description]
  * @return {[type]}         [description]
  */
 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;
};

 /**
  * [function jsonp]
  * @param  {[type]} url      [description]
  * @param  {[type]} onsucess [description]
  * @param  {[type]} onerror  [description]
  * @param  {[type]} charset  [description]
  * @return {[type]}          [description]
  */
util.jsonp = function (url, onsuccess, onerror,charset) {
    var callbackName = util.getName('tt_player'); // 加載script標籤的形式
    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);
};


// AJAX
util.extend(opt,options);
if(opt.url){
    // 聲明XMLHttpRequest 對象的工做流程
    var xhr = XMLHttpRequest ? new XMLHttpRequest () : new window.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 +'?' + dataArry.join('&');
        xhr.open(type,url.replace(/\?$/g,''),true);
        xhr.send();
    }
    if (type === 'POST') {
        xhr.open(type,url,true);
        xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
        xhr.send(dataArry.join('&'));
    }
    // 監聽它成功失敗
    xhr.onload = function () {
        // 200:客戶端請求成功 304:重定向,利用本地緩存
        if (xhr.status === 200 || xhr.status === 304 ) { // 媒體資源加206
            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); 
                }
            }
        }
    }
    
export default util;
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>通訊類</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" media="screen" href="main.css" />
    <script src="main.js"></script>
</head>

<body>
    <script>
        // 建立ajax【參考網址】https://segmentfault.com/a/1190000006669043
        // 參考jsonp.js
    </script>

    <script src="http://www.abc.com/?data=name&callback=jsonp"></script>
    <script type="text/javascript">
        // jsonp({
        //     data: {
        //
        //     },
        // });
    </script>
    <script type="text/javascript">
        /**
         * 跨域通訊的幾種方法
         */

        // jsonp工做原理,參考jsonp.js


        // 利用hash,場景是當前頁面 A 經過iframe或frame嵌入了跨域的頁面 B
        // 在A中僞代碼以下:
        var B = document.getElementsByTagName('iframe');
        B.src = B.src + '#' + 'data';
        // 在B中的僞代碼以下
        window.onhashchange = function () {
            var data = window.location.hash;
        };

        // postMessage
        // 窗口A(http:A.com)向跨域的窗口B(http:B.com)發送信息
        Bwindow.postMessage('data', 'http://B.com'); // B 窗口下的 window 
        // 在窗口B中監聽
        Awindow.addEventListener('message', function (event) {
            console.log(event.origin); // http://A.com
            console.log(event.source); // Awindow
            console.log(event.data); // data
        }, false);

        // Websocket【參考資料】http://www.ruanyifeng.com/blog/2017/05/websocket.html

        var ws = new WebSocket('wss://echo.websocket.org'); // ws加密 wss非加密

        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【參考資料】http://www.ruanyifeng.com/blog/2016/04/cors.html
        // url(必選),options(可選)
        // 新的 API
        fetch('/some/url/', {
            method: 'get',
        }).then(function (response) {

        }).catch(function (err) {
            // 出錯了,等價於 then 的第二個參數,但這樣更好用更直觀
        });
    </script>
</body>

</html>

Licensecss

  • 能夠拷貝、轉發,可是必須提供原做者信息,同時也不能將本項目用於商業用途。
相關文章
相關標籤/搜索