web前端跨域解決方案JSONP,CORS,NGINX反向代理

世有因果知因求果發表於2019-04-30

https://blog.csdn.net/hansexploration/article/details/80314948

http://www.cnblogs.com/yuzhongwusan/archive/2012/12/11/2812849.html

什麼是跨域以及產生原因

  跨域是指a頁面想獲取b頁面資源,如果a、b頁面的協議、域名、埠、子域名不同,或是a頁面為ip地址,b頁面為域名地址,所進行的訪問行動都是跨域的,而瀏覽器為了安全問題一般都限制了跨域訪問,也就是不允許跨域請求資源。比如,Ajax直接請求普通檔案存在跨域無許可權訪問的問題,甭管你是靜態頁面、動態網頁、web服務、WCF,只要是跨域請求,一律不準 

 

僅支援get操作的JSONP的產生過程:

1、Web頁面上呼叫js檔案時則不受是否跨域的影響(不僅如此,我們還發現凡是擁有”src”這個屬性的標籤都擁有跨域的能力,比如<\script>、<\img>、<\iframe>)。

2、於是可以判斷,當前階段如果想通過純web端(ActiveX控制元件、服務端代理、屬於未來的HTML5之Websocket等方式不算)跨域訪問資料就只有一種可能,那就是在遠端伺服器上設法把資料裝進js格式的檔案裡,供客戶端呼叫和進一步處理。

3、恰巧我們已經知道有一種叫做JSON的純字元資料格式可以簡潔的描述複雜資料,更妙的是JSON還被js原生支援,所以在客戶端幾乎可以隨心所欲的處理這種格式的資料。

4、這樣子解決方案就呼之欲出了,web客戶端通過與呼叫指令碼一模一樣的方式,來呼叫跨域伺服器上動態生成的js格式檔案(一般以JSON為字尾),顯而易見,伺服器之所以要動態生成JSON檔案,目的就在於把客戶端需要的資料裝入進去。

5、客戶端在對JSON檔案呼叫成功之後,也就獲得了自己所需的資料,剩下的就是按照自己需求進行處理和展現了,這種獲取遠端資料的方式看起來非常像AJAX,但其實並不一樣。

6、為了便於客戶端使用資料,逐漸形成了一種非正式傳輸協議,人們把它稱作JSONP,該協議的一個要點就是允許使用者傳遞一個callback引數給服務端,然後服務端返回資料時會將這個callback引數作為函式名來包裹住JSON資料,這樣客戶端就可以隨意定製自己的函式來自動處理返回資料了。

我們看看以下幾個實體, jsonp.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
    // 得到航班資訊查詢結果後的回撥函式
    var flightHandler = function(data){
        alert('你查詢的航班結果是:票價 ' + data.price + ' 元,' + '餘票 ' + data.tickets + ' 張。');
    };
    // 提供jsonp服務的url地址(不管是什麼型別的地址,最終生成的返回值都是一段javascript程式碼)
    var url = "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998&callback=flightHandler";
    // 建立script標籤,設定其屬性
    var script = document.createElement('script');
    script.setAttribute('src', url);
    // 把script標籤加入head,此時呼叫開始
    document.getElementsByTagName('head')[0].appendChild(script); 
    </script>
</head>
<body>
 
</body>
</html>

對應處理jsonp請求的後端程式碼,核心任務就是返回一個包括json資料的函式呼叫js程式碼。這段js程式碼會在web客戶端執行,而flightHandler函式是在前端定義的。

echo '
flightHandler({
    "code": "CA1998",
    "price": 1780,
    "tickets": 5
}'

JSONP一句話原理總結:

利用script標籤繞過同源策略,獲得一個類似以下的js函式呼叫,jsonpcallback是頁面存在的回撥方法,而資料就以函式引數的形式儲存在callback函式引數中。

jsonpcallback({"Email":"zhww@outlook.com","Remark":"我來自遙遠的東方"})

jsonp的缺點:

僅僅支援get請求

CORS:支援所有get, post跨域請求

從上面的討論我們知道jsonp雖然可以一定程度上解決跨域的get請求資料訪問問題,但是無法支援post操作。這時CORS就可以較好解決這個問題。但是CORS必須伺服器配合配置來完成。

CORS的基本原理是客戶端Origin頭欄位+伺服器的以下配置實現

Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000

NGINX反向代理完美解決跨域問題

上面已經說到,禁止跨域問題其實是瀏覽器的一種安全行為,而現在的大多數解決方案都是用標籤可以跨域訪問的這個漏洞或者是技巧去完成,但都少不了目標伺服器做相應的改變,而我最近遇到了一個需求是,目標伺服器不能給予我一個header,更不可以改變程式碼返回個script,所以前5種方案都被我否決掉。最後因為我的網站是我自己的主機,所以我決定搭建一個nginx並把相應程式碼部署在它的下面,由頁面請求本域名的一個地址,轉由nginx代理處理後返回結果給頁面,而且這一切都是同步的。

https://www.cnblogs.com/gabrielchen/p/5066120.html

相關文章