javascript 跨域 的幾種方法

 

1.jsonp方法javascript

轉:https://blog.csdn.net/liusaint1992/article/details/50959571php

主要實現功能:html

1.參數拼裝。java

2.給每一個回調函數惟一命名。web

3.在回調成功或請求失敗以後刪除建立的javascript標籤。 須要兼容IE。IE下onerror事件不兼容。這裏有對它的模擬實現。在IE下加載失敗也能get到。chrome

4.超時功能。超時取消回調。執行error。json

5.error事件。可執行本身傳入的error事件。跨域

代碼封裝,調用,以及後臺代碼以下服務器

/*author:ls <841766635@qq.com> 
* data:2016/03/20 
*/  
  
function JSONP(url,config){  
    var data = config.data || [];  
    var paraArr=[],paraString='';//get請求的參數。  
    var urlArr;  
    var callbackName;//每一個回調函數一個名字。按時間戳。  
    var script,head;//要生成script標籤。head標籤。  
    var supportLoad;//是否支持 onload。是針對IE的兼容處理。  
    var onEvent;//onload或onreadystatechange事件。  
    var timeout = config.timeout || 0;//超時功能。  
  
    for(var i in data){  
        if(data.hasOwnProperty(i)){  
            paraArr.push(encodeURIComponent(i) + "=" +encodeURIComponent(data[i]));  
        }  
    }  
  
    urlArr = url.split("?");//連接中原有的參數。  
    if(urlArr.length>1){  
        paraArr.push(urlArr[1]);  
    }  
  
    callbackName = 'callback'+new Date().getTime();  
    paraArr.push('callback='+callbackName);  
    paraString = paraArr.join("&");  
    url = urlArr[0] + "?"+ paraString;  
  
    script = document.createElement("script");  
    script.loaded = false;//爲了實現IE下的onerror作的處理。JSONP的回調函數老是在script的onload事件(IE爲onreadystatechange)以前就被調用了。所以咱們在正向回調執行之時,爲script標籤添加一個屬性,而後待到onload發生時,再檢測有沒有這個屬性就能夠斷定是否請求成功,沒有成功固然就調用咱們的error。  
  
    //將回調函數添加到全局。  
    window[callbackName] = function(arg){  
        var callback = config.callback;  
        callback(arg);  
        script.loaded = true;  
    }  
  
    head = document.getElementsByTagName("head")[0];  
    head.insertBefore(script, head.firstChild) //chrome下第二個參數不能爲null  
    script.src = url;  
  
    supportLoad = "onload" in script;  
    onEvent = supportLoad ? "onload" : "onreadystatechange";  
  
    script[onEvent] = function(){  
  
        if(script.readyState && script.readyState !="loaded"){  
            return;  
        }  
        if(script.readyState == 'loaded' && script.loaded == false){  
            script.onerror();  
            return;  
        }  
        //刪除節點。  
        (script.parentNode && script.parentNode.removeChild(script))&& (head.removeNode && head.removeNode(this));    
        script = script[onEvent] = script.onerror = window[callbackName] = null;  
  
    }  
  
    script.onerror = function(){  
        if(window[callbackName] == null){  
            console.log("請求超時,請重試!");  
        }  
        config.error && config.error();//若是有專門的error方法的話,就調用。  
        (script.parentNode && script.parentNode.removeChild(script))&& (head.removeNode && head.removeNode(this));    
        script = script[onEvent] = script.onerror = window[callbackName] = null;  
    }  
  
    if(timeout!= 0){  
        setTimeout(function() {  
            if(script && script.loaded == false){  
                window[callbackName] = null;//超時,且未加載結束,註銷函數  
                script.onerror();                 
            }  
        }, timeout);  
    }  
  
}  

  

<!-- jsonp.html-->
<!DOCTYPE html>  
<html>  
<head>  
    <meta charset="utf-8">  
    <title>jsonp測試</title>  
    <script src="jsonp.js"></script>  
</head>  
<body>  
    <script>  
        function myerror(){  
            alert('there must be something wrong!');  
        }  
        function getData (data){  
            alert("服務器過來的數據是"+data);  
        }  
        var url = 'http://runningls.com/demos/2016/jsonp/jsonp.php';  
        //調用函數。  
        JSONP(url,{  
            data:{  
                id:1  
            },  
            callback:getData,  
            error:myerror,  
            timeout:10000  
        });  
    </script>  
</body>  

  

<?php   
  
$callback = $_GET['callback'];  
$id = $_GET['id'];  
  
if($id == 1){  
    $res = 'this is 1';  
}  
  
if($id == 2){  
    $res = 'this is 2';  
}  
  
$res = $callback."('$res')";  
  
echo $res;  
  
?>

  2.hash方法websocket

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

  3.postMessage

 

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

  4.webSocket方法

//websocket 【 參考質料】(http://www.ruanyifeng.com/blog/2017/05/websocket.html)
var ws = new WebSocket('wss://echo.websocket.org');
ws.onpen = 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.')  
}

  5.CORS方法

//CORS【 參考質料】(http://www.ruanyifeng.com/blog/2016/04/cors.html)
//url (必須),options(可選) fetch('/some/url',{//配置屬性才能跨域 method:'get }).then(function(response){}).catch(function(err){ //出錯了,等價於 then 的第二個參數 });
相關文章
相關標籤/搜索