2012-07-02 35 views
10

我正在爲一個移動的web應用程序,和jsonp是非常酷的跨域請求,但服務器的API不支持回調參數。所以我只能使用json從遠程服務器獲取數據。jQuery - 如何刪除跨域限制

我在jQuery中試過json,似乎不支持跨域請求。我在safari上嘗試了原始的ajax請求函數,並且它在跨域上效果很好,所以我可以在jQuery中刪除json請求的跨域限制嗎? (不是jsonp,只有json),以及如何做到這一點?

或者是否有任何其他簡單的ajax庫(跨網頁瀏覽器),並可以在跨域請求上執行json。

+1

你會可能會找到[迴避同源策略]的答案中的問題的答案(http://stackoverflow.com/questions/3076414/ways-to-circumvent-the-same-origin-policy)。你的問題似乎基本上是一樣的。 –

+0

我正在使用YQL + jQuery來訪問跨域內容。 –

回答

31

同源策略

您試圖規避Same Origin Policy。它內置於每個瀏覽器中,通常不會或者應該禁用/解決方法/等。這是您的網站,用戶和用戶瀏覽器之間非常重要的安全合同。

CORS(可能)

CORS讓您的網絡服務器可以告訴瀏覽器/訪問到其他域客戶端是允許的。這是由Web服務器

Access-Control-Allow-Origin: http://www.example.com 

具有以下HTTP頭輸出做如果你無法控制你的HTTP頭,那麼你就不能使用CORS。這是語言/框架的具體實現。

請注意,您應該檢查以確保browser compatibility IE8/9的支持有限。另外請注意,這是一個潛在的攻擊媒介。如果您不負責任地使用響應數據,它允許來自第三方站點的響應執行XSS攻擊。

JSONP(可能的)

JSONP是通過和通過動態地添加script標籤與src atrribute等於"yoururl.com?<your parameter data>"到網頁獲取服務器之間的數據一個聰明的方式。這是在沒有Web代理(見下文)或小程序(Flash/Java)的情況下完成這項壯舉的唯一合法方式。但是,如果您不是請求兩端的提供者,它確實有其自身的安全風險。請記住,JSONP允許遠程服務器在您的上下文中執行代碼,您應該是very careful who you give that power to

「香草」 AJAX(不可能)

如果你不使用JSONP獲取數據,那麼你最有可能嘗試使用一個AJAX請求來獲取數據。 AJAX請求也受到同源策略的限制。 JavaScript庫(例如jQuery,Prototype,Dojo等)不能繞過這個策略作爲Ajax請求的基本行爲。但是,他們可以支持JSONP(現在記得,不是AJAX)。

AJAX W/Web代理服務器(可能)

如果你想從另一臺服務器請求數據時,您可以轉發您的請求。您的主站點的服務器將充當代理。您需要向自己的服務器發出AJAX請求,然後服務器端代碼將向另一個域發出請求,然後通過AJAX調用響應將響應發送到您的腳本。

這是一種常見的模式,它在這裏被詳細描述爲Web Proxy Pattern和友好的雅虎一個here (but remember it's Yahoo specific, just take the general idea)。然而,它依賴於服務器端語言。整體實現將是相同的,但是這樣做的代碼會根據您選擇的服務器端語言(PHP,Ruby,Python,C等)而有所不同。有些語言已經有庫/模塊/等支持這種模式。

閃存(可能的話,非默認)

的Flash在默認狀態下不支持跨域請求。它可以在Flash7 +中打開,使用cross-domain policy files,但強烈建議不要。您的腳本將不得不與Flash API進行接口,以便發出請求並將數據返回給JavaScript。

Java小程序(可能,非默認)

的Java也受到同樣的原產地政策,但也有類似的變通到Flash作爲described here on its release

其他各種「黑客」

還有其他的黑客那裏,但他們通常需要你控制兩端或者在標準通信商定。例如'window.name'破解。我不建議大部分這些方法。

其他解決方案

類似於此的另一個問題已經被問。它概述了我沒有涵蓋一些其他的方法:Ways to circumvent the same-origin policy

的最佳解決方案

  1. CORS - 如果你信任的第三方
  2. Web代理 - 如果你不這樣做

您自己的域上的網絡代理可以讓您清理正在檢索的數據,它爲您的用戶提供最大的保護。但是,如果您的衛生設施爲零,則不會比此處列出的任何方法更安全。如果您確實實施了某種網絡代理,請確保其請求僅限於您希望的網站。否則,你將基本上創建一個open proxy,如果發現用戶可能會濫用它,並且讓你陷入法律糾紛。

4

做這將是我所做過下面對一個個人項目啓用跨站點執行

請注意,這將是接收服務器無法發送上完成的,而俗氣的方法之一

if ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') === FALSE) 
     die('You shouldn\'t be here'); 

    header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); 
    header('Access-Control-Allow-Methods: POST, GET, OPTIONS'); 
    header('Access-Control-Max-Age: 1000'); 
    header('Access-Control-Allow-Headers: Content-Type'); 

,如果你希望它是安全些,你可以做

if ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') === FALSE) 
     die('You shouldn\'t be here'); 

switch($_SERVER['HTTP_ORIGIN']){ 
case 'domain.com': 
case 'whatever.com': 
     header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); 
     header('Access-Control-Allow-Methods: POST, GET, OPTIONS'); 
     header('Access-Control-Max-Age: 1000'); 
     header('Access-Control-Allow-Headers: Content-Type'); 
} 

希望這有助於我花了永遠的數字出來大聲笑。

+8

你可以在你描述的方法中添加一些[引用](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing),即[CORS](http://www.w3.org/TR/) CORS /)。 –

6

我有同樣的問題。試圖從服務器獲取json,以至於我無法訪問(=>沒有JSONP)。

我找到了http://benalman.com/projects/php-simple-proxy/將php代理添加到您的服務器並對此文件執行ajax調用。 「要傳遞給遠程URL資源的任何GET參數必須在此參數中進行urlencode。」

$.ajax({ 
    type: 'GET', 
    url:'proxy.php?url=http://anyDomain.com?someid=thispage', 
    dataType: "json", 
    success: function(data){ 
     // success_fn(data); 
    }, 
    error: function(jqXHR, textStatus, errorThrown) { 
     // error_fn(jqXHR, textStatus, errorThrown); 
    } 
}); 

其中proxy.php(距離Ben Alman文件)在您的域名


另類(我認爲是退而求其次,這一點)託管: http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/

+0

好的,謝謝! – Tom