1. 程式人生 > >前端跨域通訊的幾種方式

前端跨域通訊的幾種方式

一、JSONP

我們都知道script標籤src屬性中的連結卻可以訪問跨域的js指令碼,利用這個特性,服務端不再返回JSON格式的資料,而是返回一段呼叫某個函式的js程式碼,在src中進行了呼叫函式來獲取到資料,函式中的引數就是我們需要的資料,這樣實現了跨域。
基本思想是:
1、客戶端利用script標籤可以跨域請求資源的性質,向網頁中動態插入script標籤,來向服務端請求資料。
2、服務端會解析請求的url,至少拿到一個回撥函式(比如callback=myCallback)引數,之後將資料當做函式引數放入其中返回給客戶端。
3、當然jsonp僅支援get型別的方式

下面我們將舉例說明:


需要跨域請求的地址是:
https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=hello&sugmode=2&json=1&p=3&sid=1449_21106_27377&req=2&bs=hello&pbs=hello&csor=5&pwd=hello&cb=jQuery110203960180958059971_1542965283806&_=1542965283817

1、原生js方式實現jsonp
<!-- 我們來抓取百度搜索的介面資料(在文章釋出時我測試過能正常訪問,如果之後介面有改版請自行找其他介面測試) -->
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>jsonp</title> <script> //jsonhandle函式名要和請求的callback引數名一致,在這裡是url引數中的cb=jsonhandle function jsonhandle(data){ //請求到介面後返回的資料就在這裡進行處理 console.log(data); }
</script> <script type="text/javascript"> window.onload = function(){ var body = document.body; var oInput = document.getElementById("search"); var oBtn = document.getElementById("btn"); //點選按鈕之後才動態新增script標籤進行jsonp請求 oBtn.onclick = function(){ var text = oInput.value; //wd引數是搜尋的關鍵字,我們可以動態改變,進行字串拼接即可 var url = "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd="+text+"&sugmode=2&json=1&p=3&sid=1449_21106_27377&req=2&bs=hello&pbs=hello&csor=5&pwd=hello&cb=jsonhandle&_=1542965283817"; var scriptDom = document.createElement("script"); scriptDom.src = url; body.appendChild(scriptDom); }; } </script> </head> <body> <div class="wrap"> <input type="text" placeholder="百度一下你就知道" id="search" autocomplete="off"> <input type="button" value="百度" id="btn"> </div> </body> </html>

其實原理就是:我們在輸入框輸入了關鍵字之後,點選按鈕就會在頁面中動態添加了一個script標籤,這個標籤就是去請求介面的,然後返回來的資料格式是jsonhandle("請求到的資料作為了函式的引數"),這裡就相當於函式jsonhandle被呼叫,然後我們之前在上面定義了函式function jsonhandle(data){ }在此時就被呼叫了,那麼引數data就是獲取到的資料,這時候就可以在定義的函式中進行資料處理了。

2、jquery提供的便捷式方式實現jsonp
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>jsonp</title>
    <!-- 引入jquery的cdn -->
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
    $(function(){
        //點選按鈕後才進行jsonp跨域請求
        $("#btn").click(function(){
            var text = $("#search").val();
            $.ajax({
                type : "get",
                url : "https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd="+text+"&sugmode=2&json=1&p=3&sid=1449_21106_27377&req=2&bs=hello&pbs=hello&csor=5&pwd=hello&_=1542965283817",
                dataType: "jsonp",
                jsonp:"cb", //請求回撥函式的引數名,如cb=jsonhandle,這裡就需要寫cb
                jsonpCallback: "jsonhandle",//要執行的回撥函式名(自定義)
                success : function(data) { //這裡就是請求介面後得到的資料,在這個函式進行資料處理
                    console.log(data)
                }

            });
        })
        
    });
</script>
</head>
<body>
    <div class="wrap">
        <input type="text" placeholder="百度一下你就知道" id="search" autocomplete="off"> 
        <input type="button" value="百度" id="btn">
    </div>
</body>
</html>

二、hash

原理是利用location.hash來進行傳值。在url: http://a.com#hello中的"#hello"就是location.hash,改變hash並不會導致頁面重新整理,所以可以利用hash值來進行資料傳遞,當然資料容量是有限的(就和get請求一樣,引數長度有限制)。

//利用hash的場景是,當頁面A通過iframe嵌入了跨域的頁面B
//在頁面A中的虛擬碼如下:
var Biframe = document.getElementByTagName("iframe");
Biframe.src = Biframe.src + "#" + 'datas' //這裡的datas可以是json型別的字串,就是要傳給B頁面的資料

//在頁面B中的虛擬碼如下:
window.onhashchange = function(){
	var data = window.location.hash;  // 這裡獲取到B頁面url地址#號後面的所有資料
}

三、postMessage

HTML5新增的解決跨域的知識點。
postMessage()方法允許來自不同源的指令碼採用非同步方式進行有限的通訊,可以實現跨文字檔、多視窗、跨域訊息傳遞。

參考帖子:https://blog.csdn.net/m0_38134431/article/details/83344894

四、WebSocket

不受同源限制,所以就能進行跨域請求了。
在這裡插入圖片描述

五、CORS

支援跨域通訊的ajax。在使用ajax傳送請求的時候在請求頭中加入一個origin來允許跨域通訊。
CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。
它允許瀏覽器向跨源伺服器,發出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。

在這裡插入圖片描述
上面的程式碼是同源請求方式、如果需要跨域就要配置相應請求頭。

CORS原理參考網址:http://www.ruanyifeng.com/blog/2016/04/cors.html

CORS跨域使用Fetch API (ES6的知識點)

在這裡插入圖片描述在這裡插入圖片描述在這裡插入圖片描述
Fetch API原帖子:https://www.jianshu.com/p/35123b048e5e