在分配location.href时,请解释url编码(在asp.net和firefox中)

时间:2010-01-22 07:47:53

标签: asp.net javascript url-encoding

在某些javascript中,我有:

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

其中address的值是字符串“Seattle,WA”。

在警报中我看到了

find.aspx?Seattle%2C%20WA

正如我所料。

但是在服务器端,当我查看Request.Url时,我看到的相关子字符串是

find.aspx?Seattle, WA

在Firefox网址窗口中,我看到了

find.aspx?location=Seattle%2C WA

所以我得到了三种不同的表现形式,而我希望在这三个地方我都应该看到我在警报中看到的内容。我的期望是我分配给location.href的url应该在浏览器url窗口中显示为as-is,并且应该按原样传递给Request.Url中的服务器(我需要解码服务器上的值)在使用它们之前)。发生了什么事?

3 个答案:

答案 0 :(得分:2)

Firefox将某些编码字符转换为文字形式,以便对用户友好。它还会将键入地址栏的空格转换为服务器的%20。

更新:Firefox未显示未编码的逗号的原因是因为URL中允许使用逗号,但空格不允许,因此知道空间正在进行明确地解释,而预编码的逗号不同于一些服务器的非编码逗号。见:Can I use commas in a URL?

ASP可能会尝试通过为您自动解码字符串来帮助您。

更新:默认情况下,ASP.NET看起来像是为了取消对Request.Url的编码,如下所述:QueryString malformed after URLDecode他们还提到您可以使用HttpRequest.Url.Query来访问未解码的版本。

警报是唯一不为你做任何“魔法”的事情。

答案 1 :(得分:1)

对于警报,您自己正在进行编码。如果您删除encodeURIComponent,它可能与服务器端看起来相同。

在服务器端,ASP.NET将始终显示未编码的表单。这样可以更容易地直接映射到也具有需要(未)编码的文本的文件。

请注意,您可以在URL编码中替换其UTF8表示形式的每个字母。它仍然是相同的URL。即,在浏览器窗口中键入以下内容,它仍然有效:%66%59%6E%64.aspx?location=Seattle%2C%20WA。要仅编码必要的字符,请在服务器端使用UrlEncode,如果您自己创建链接。

网址编码可能会变得非常棘手。你要求解释一下。要知道某个字符的正确转义,您需要知道该字符在UTF8中的外观。然后,UTF-8字节的十六进制值将成为字母的%XX%YY值。有时它是一个%XX,但总共可以有六个字节的序列(例如一些中文字符)。

网址编码仅适用于一种方式。永远不要双重编码或双重编码。这是规范禁止的。此外,因为您可以对任何字符进行编码,所以并不总是可以(如您所知)进行往返编码/取消编码。如果你再次编码和重新编码,结果字符串很可能是不同的,但语法上是相同的。

在HTML中,网址为Encoding is sometimes interspersed with HTML Encoding。即,&符号在HTML中有效,但在HTML中无效。 find.aspx?city=A&name=B成为find.aspx?city=A&name=B和HTML网址。但是,浏览器是宽松的,并且会接受错误的HTML编码字符串。

最后,不在浏览器上:如果您在链接中键入空格,即使在<a>标记内,它也会为您释放空格(或其他字符)。同样,它现在会在地址栏中显示奇数字符(é,ïetc),但是当它通过HTTP发送时,浏览器会正确地为您编码。


更新: ,了解有关需要“明确”参考或证据的问题。

虽然我在互联网上找不到任何东西,但我决定自己使用Reflector寻找它。通过设置HttpRequest.QueryString的方法,您很快就会遇到私有方法HttpRequest.FillInQueryStringCollection,然后调用HttpValueCollection.FillfromEncodedBytes。接近该方法的末尾,为值调用HttpUtility.UrlDecode。结论:不要自己调用,以防止双重解码。

下载Reflector并反汇编System.Web的.NET库时,您可以自己查看。

答案 2 :(得分:0)

对于您的示例,您可以更改此行

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

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

并查看地址。如果地址变量包含任何'&amp;'你的变量将被破坏的字符。所以你使用encodeURIComponent来编码这些东西url。

在服务器端,所有这些编码的字符串都被解码回来。这意味着encodeURIComponent只是用于正确地向服务器端发送地址变量(无论它是否包含&amp;字符)。