2009-08-02 49 views
10

這很奇怪,我想知道是否有人可以闡明爲什麼會發生這種情況。當在本地主機上運行時JSONP回調不會執行

基本上,我一直拉着我的頭髮出來試圖測試JSONP出來,所以我可以實現JSON Web服務,其他網站可以使用。我正在開發本地主機 - 特別是Visual Studio 2008和Visual Studio 2008內置的Web服務器。

所以,作爲一個JSONP試運行瓦特/ jQuery的,我實現了以下內容:

$().ready(function() { 
    debugger; 
    try { 
    $.getJSON("<%= new Uri(Request.Url, "/").ToString() %>XssTest?callback=?", function(data) { 
     alert(data.abc); 
    }); 
    } catch (err) { 
    alert(err); 
    } 
}); 

並在服務器上..

<%= Request["callback"] %>({abc : 'def'}) 

那麼最終發生的是我設置一個斷點上服務器和我在第一個「調試器」上得到斷點;在客戶端腳本中以及在服務器上進行統計。 JSONP URL確實在頁面加載後被調用。這很好。

我遇到的問題是回調永遠不會執行。我在IE8和Firefox 3.5中測試了這個。兩者都不會調用回調。 catch(err)也從來沒有達到過。什麼都沒發生!

我一直停留在這一個星期,甚至在指定的端口上,以Telnet手動密鑰的HTTP請求,以確保服務器返回的格式測試...

callbackfn({abc : 'def'}) 

..它是。

然後,我明白了,如果我從本地主機更改主機名與一個全球化者本地主機(「」),即http://localhost.:41559/代替http://localhost:41559/(是的,增加一個點到任何主機名是合法的,這是DNS什麼global::是C#命名空間)。然後它工作!當我剛添加一個點時,Internet Explorer和Firefox 3.5終於向我顯示了一條警告消息。

所以這讓我想知道這是怎麼回事?爲什麼後期腳本標記生成可以使用Internet主機名而不是使用純本地主機?或者這是正確的問題?

顯然這是出於安全原因而實施的,但他們試圖保證什麼?而且,通過使用點來工作,我是否在此安全功能中暴露了安全漏洞?

順便說一句,我的主機文件,雖然改變了其他主機,沒有什麼特別與本地主機進行;默認的127.0.0.1/:: 1仍然存在,下面沒有覆蓋。

追問:我過去,這爲當地發展的目的,加入:

127.0.0.1 local.mysite.com 

..我的hosts文件,然後將以下代碼添加到我的Global.asax:

protected void Application_BeginRequest(object sender, EventArgs e) 
{ 
    if (Request.Headers["Host"].Split(':')[0] == "localhost") 
    { 
     Response.Redirect(
      Request.Url.Scheme 
      + "://" 
      + "local.mysite.com" 
      + ":" + Request.Url.Port.ToString() 
      + Request.Url.PathAndQuery 
      , true); 
    } 
} 
+0

我建議使用像firebug這樣的工具,看看是否爲JSONP的東西完成了「腳本」請求,並且實際上看到了什麼數據會回來。 – 2009-08-02 01:32:56

回答

3

我打算在那裏提出答案;經過一番思考我已經達到了我自己的結論。

這可能是因爲這是一個安全功能,它試圖阻止Internet網站調用運行在客戶機上的JSONP服務。

一個網站可能只是通過一個端口列表,並保持調用localhost在不同的端口和路徑。 'Localhost'是少數DNS主機名稱之一,它的含義是動態的,取決於查詢的時間和地點,使潛在目標易受攻擊。是的,爲'localhost'('localhost。')附加一個點(。)產生一個工作解決方法確實暴露了一個安全漏洞,但確實爲開發目的提供了一個[暫定]解決方法。

更好的方法是將回送IP映射到hosts文件中的新主機名項,以便它在本地工作,不容易被瀏覽器更新「修復」,並且在其他任何地方都無法工作,但在開發工作站上。

1

我遇到了類似的問題。我嘗試過的大多數解決方案都使用IE(7),但我很難讓Firefox(3.5.2)玩球。

我已經安裝了HttpFox,以查看我的服務器的響應是如何在客戶端上解釋的,而且我得到了NS_ERROR_DOM_BAD_URI。雖然我的情況與你的情況稍有不同,因爲我試圖調用JSONP調用回到託管頁面來自的同一站點,然後此調用以302重定向到另一站點進行響應。 (我使用重定向作爲一種方便的方式來從兩個域返回瀏覽器的cookies。)

我使用jQuery,我最初嘗試通過$ .ajax()進行標準AJAX調用。我認爲,由於最初的請求是作爲託管頁面的同一網站,Firefox只會遵循302對另一個域的響應。但是,不,它似乎與XSS防守有關。 (請注意,與Returning redirect as response to XHR request暗示的不同,jQuery確實遵循標準dataType =「json」調用的302重定向:重定向到同一個域可以正常工作;重定向到另一個域會在瀏覽器中生成NS_ERROR_DOM_BAD_URI。)另外,我不明白爲什麼同域302重定向到其他域不能被遵循 - 畢竟,它是發佈重定向的主機頁的域,爲什麼它不被信任?如果你擔心腳本注入攻擊,那麼JSONP路由是開放的濫用...

jQuery的$ .getJSON()與?回調=?後綴在Firefox中也出現了相同的錯誤。正如使用$ .getScript()來滾動我自己的JSONP <腳本>標記。

什麼確實出現了工作,是一種在HTML預先存在<腳本ID = 「JSONP」 類型= 「文/ JavaScript的」 > < /腳本>,然後使用$( 「JSONP」)。ATTR( 「src」,url +「?callback = myCallback」)來調用JSONP調用。如果我這樣做,那麼跨域302重定向被跟隨,並且我得到我的JSON響應傳遞給myCallback(我已經同時定義了<腳本/ >標記)。

而且,是的,我正在開發所有使用本地主機的Cassini:端口的URL。 Cassini不會對非本地主機URL做出響應,所以我不能輕易嘗試local.mysite.com來查看這對我上面嘗試的解決方案是否有任何影響。但是,在本地主機的末端添加一個點似乎已經解決了我所有的問題!

現在我可以回去標準$阿賈克斯({...數據類型: 「JSONP」 ...})與本地主機調用__.__:端口以代替localhost:端口,一切都很好。我覺得有趣的是,修改頁面的HTML 中預先存在的腳本標記的src屬性,允許調用普通的本地主機URL - 我想按照您的思考過程,這可能是另一個安全漏洞。

相關問題