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

http://www.javashuo.com/article/p-bbnotdik-ep.htmljavascript

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

什麼是跨域以及產生緣由

  跨域是指a頁面想獲取b頁面資源,若是a、b頁面的協議、域名、端口、子域名不一樣,或是a頁面爲ip地址,b頁面爲域名地址,所進行的訪問行動都是跨域的,而瀏覽器爲了安全問題通常都限制了跨域訪問,也就是不容許跨域請求資源。好比,Ajax直接請求普通文件存在跨域無權限訪問的問題,甭管你是靜態頁面、動態網頁、web服務、WCF,只要是跨域請求,一概不許 前端

 

僅支持get操做的JSONP的產生過程:

一、Web頁面上調用js文件時則不受是否跨域的影響(不只如此,咱們還發現凡是擁有」src」這個屬性的標籤都擁有跨域的能力,好比<\script>、<\img>、<\iframe>)。java

二、因而能夠判斷,當前階段若是想經過純web端(ActiveX控件、服務端代理、屬於將來的HTML5之Websocket等方式不算)跨域訪問數據就只有一種可能,那就是在遠程服務器上設法把數據裝進js格式的文件裏,供客戶端調用和進一步處理。nginx

三、恰巧咱們已經知道有一種叫作JSON的純字符數據格式能夠簡潔的描述複雜數據,更妙的是JSON還被js原生支持,因此在客戶端幾乎能夠爲所欲爲的處理這種格式的數據。web

四、這樣子解決方案就呼之欲出了,web客戶端經過與調用腳本如出一轍的方式,來調用跨域服務器上動態生成的js格式文件(通常以JSON爲後綴),顯而易見,服務器之因此要動態生成JSON文件,目的就在於把客戶端須要的數據裝入進去。json

五、客戶端在對JSON文件調用成功以後,也就得到了本身所需的數據,剩下的就是按照本身需求進行處理和展示了,這種獲取遠程數據的方式看起來很是像AJAX,但其實並不同。後端

六、爲了便於客戶端使用數據,逐漸造成了一種非正式傳輸協議,人們把它稱做JSONP,該協議的一個要點就是容許用戶傳遞一個callback參數給服務端,而後服務端返回數據時會將這個callback參數做爲函數名來包裹住JSON數據,這樣客戶端就能夠隨意定製本身的函數來自動處理返回數據了。api

咱們看看如下幾個實體, 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代理處理後返回結果給頁面,並且這一切都是同步的。

http://www.javashuo.com/article/p-ysxaijvn-bd.html

相關文章
相關標籤/搜索