2010-01-22 24 views
2

在一些JavaScript,我有:分配location.href時,請解釋URL編碼(在asp.net和Firefox)

var url = "find.aspx?" + "location=" + encodeURIComponent(address); 
alert(url); 
location.href = url; 

,其中地址的值是字符串 「西雅圖」。

在警告我看到

find.aspx?Seattle%2C%20WA 

如我所料。

但在服務器端,當我在看Request.Url,相關子我看到的是

find.aspx?Seattle, WA 

而在Firefox的URL窗口我看到

find.aspx?location=Seattle%2C WA 

所以我得到三種不同的表述,而我希望在這三個地方我都能看到我在警戒中看到的東西。我的期望是,我分配給location.href的url應該顯示在瀏覽器的url窗口中,並且應該原樣傳遞給Request.Url中的服務器(並且我需要解碼服務器上的值在使用它們之前)。發生了什麼?

+0

@M Katz:關於你的另一個問題,在一些評論中提到,有關「證明」的參考資料,請參閱我的更新。 (此評論不會保留) – Abel 2010-01-22 12:47:35

回答

2

Firefox將某些編碼字符轉換爲它們的字面形式,作爲對用戶友好的一種方式。它還會將輸入到地址欄的空格轉換爲服務器的%20。

更新:之所以Firefox不顯示逗號未編碼是因爲逗號被允許在URL中,但空間都沒有,所以它知道一個空間將被明確地解釋,而預編碼的逗號與某些服務器的非編碼逗號不同。請參閱:Can I use commas in a URL?

ASP可能試圖通過爲您自動解除字符串編碼來幫助您。

更新:它看起來像ASP.NET unencodes Request.Url你在默認情況下,這裏提到:QueryString malformed after URLDecode他們還提到,您可以使用HttpRequest.Url.Query訪問未解碼的版本。

警報是唯一沒有爲你做任何「魔術」的事情。

+0

感謝您的快速回復。如果firefox試圖顯示友好版本的url,爲什麼它會離開%2c而不是將它顯示爲逗號?至於ASP.NET,如果它只是試圖「幫助我」,這似乎令人困惑。你知道它記錄在哪裏嗎?我必須知道它是否總是解密,否則我可以通過解密兩次來搞砸,對吧? – 2010-01-22 07:58:49

+0

URL規範禁止兩次編碼,並且確實會搞砸了。相同的解碼。這樣,可以保證你可以將%2C編碼爲一個字符串:'google/search?q =%252C'將搜索「%2C」而不是「,」(雙重解碼)。 – Abel 2010-01-22 08:15:33

+0

你的更新的後續:'Request.QueryString.ToString()'被覆蓋並給出一個重新編碼的版本。 'bla.aspx?a =%20b'返回'a = + b',而'QueryString [「a」]'會返回'「b」'(不含引號)。另請注意,Request.RawUrl給出確切的輸入GET請求(通常*不包括主機和協議部分),Request.Url.Query給出未解碼的輸入查詢字符串*,包括問號*。也許總是有點凌亂,但是一旦你知道什麼是...... ;-) – Abel 2010-01-24 15:55:22

0

爲了您的例子中,你可以把這個信號

var url = "find.aspx?" + "location=" + encodeURIComponent(address); 

改變

var url = "find.aspx?" + "location=" + address; 

,看到的地址,因爲它是。如果地址變量包含任何'&'字符,你的變量將被破壞。所以你使用encodeURIComponent來編碼這些東西的URL。

在服務器端,所有這些編碼字符串都被解碼回來。這意味着encodeURIComponent僅用於將地址變量(無論是否包含&字符)正確地發送到服務器端。

+0

謝謝。你能幫我找到它的記錄,ASP.NET會自動爲你解開URL(如果有的話)嗎? – 2010-01-22 08:05:33

+0

我假設:UrlDecodes就是你的意思。它不會對任何內容進行編碼,您必須爲您創建的每個鏈接自己執行此操作。 – Abel 2010-01-22 12:49:00

1

對於警報,您自己正在編碼。如果你刪除了encodeURIComponent,它看起來可能與服務器端相同。

在服務器端,ASP.NET將始終向您顯示未編碼的表單。這樣可以更容易地直接映射到還需要進行(未)編碼的文本的文件。

請注意,您可以在URL編碼中替換每個字母的UTF8表示形式。它仍然是相同的網址。即,在瀏覽器窗口中鍵入以下內容,它仍然可以工作:%66%59%6E%64.aspx?location=Seattle%2C%20WA。要僅編碼必需的字符,如果您自己創建鏈接,請在服務器端使用UrlEncode

URL編碼可能變得相當棘手。你要求解釋它。要知道某個角色的正確轉義,您需要知道該角色在UTF8中的外觀。 UTF-8字節的十六進制值將成爲你的字母的%XX%YY值。有時它只有一個%XX,但總共可以達到六個字節的序列(例如一些中文字符)。

URL編碼僅適用於一種方式。切勿重複編碼或雙重解碼。這是規範所禁止的。此外,由於您可以對任何字符進行編碼,因此並不總是可以(如您發現的那樣)執行往返編碼/解碼。如果您未重新編碼並重新編碼,結果字符串可能不同,但語法上相同。

在HTML中,URL Encoding is sometimes interspersed with HTML Encoding。即,&符號在HTML中有效,但不在HTML中。 find.aspx?city=A&name=B變成find.aspx?city=A&name=B和HTML網址。但是,瀏覽器是寬鬆的,並會錯誤地接受HTML編碼的字符串。

最後,不在瀏覽器上:如果您在鏈接中鍵入空格,即使在標籤內部,也會爲您跳過空格(或其他字符)。同樣,它現在將在地址欄中顯示奇數字符(é,ï等),但當它通過HTTP發送時,瀏覽器將正確地爲您執行編碼。


更新:約anwering你需要一個 「明確的」 參考或證明的問題。

雖然我在網上找不到任何東西,但我決定自己使用Reflector來尋找它。通過設置的方法,例如,HttpRequest.QueryString,您很快會遇到私有方法HttpRequest.FillInQueryStringCollection,然後調用HttpValueCollection.FillfromEncodedBytes。有點接近該方法的結尾,HttpUtility.UrlDecode被稱爲值。結論:不要自己調用它,以防止雙重解碼。

當您下載Reflector並反彙編System.Web的.NET庫時,您可以親自看到它。

+0

感謝您的所有信息。所以我現在明白,ASP.NET總是假定一個單一的編碼,並且始終爲我執行單個解碼(我仍然希望看到明確記錄的位置)。那麼,看起來Server.UrlDecode()函數不會使用太多。什麼時候你會調用這個函數? – 2010-01-22 08:28:41

+0

@M Katz:正確,UrlDecode通常不用於解碼傳入的URL。但是,有時URL會成爲查詢字符串的一部分,該字符串已經被編碼。這真的取決於你的要求,但是當我經常使用Encode時,我沒有發現自己同樣使用Decode。您可能會想到UnescapeDataString,但首先閱讀:http://blogs.msdn.com/yangxind/default.aspx – Abel 2010-01-22 12:20:51

+0

後續:解碼已在內部使用(請參閱更新)。所以迄今爲止的假設是正確的。 – Abel 2010-01-22 12:49:36