我的申请处理网址。
以下是一个例子:
https://127.0.0.1/Datei_Verz ._Änderung.gif
浏览器发送的是:
https://127.0.0.1/Datei_Verz._%C3%84nderung.gif
当未转义时(使用AtlUnescapeUrl),%C3和%84被视为不同的字符,因此我最终得到:
https://127.0.0.1/Datei_Verz ._ A“nderung.gif
因此,unescape无法识别浏览器发送复合字符而不是预先组合(使用MSDN中的解释)。
理想情况下,浏览器会用单个Unicode代码点LATIN CAPITAL LETTER A WITH DIAERESIS(U + 00C4)代表Ä,我认为它可能是URL中的%00C4。
那么如何解码初始URL?
答案 0 :(得分:4)
这与Unicode规范化(预合成字符与分解字符序列)无关。这只是一个错误的字节编码的情况。
理想情况下,浏览器会用单个Unicode代码点LATIN CAPITAL LETTER A WITH DIAERESIS(U + 00C4)代表Ä,我认为它可能是URL中的%00C4。
不:URL编码是基于字节的编码; %-escape严格是两位数(一个字节),因此%00C4
将是一个零字节,后跟文字字符C4
。
没有%-encoding覆盖一个具有单个转义序列的代码点。在转义为%nn
序列之前,必须将Unicode URL组件编码为字节。
%C4
将是Ä
的编码,但是大多数Web应用程序今天使用的编码(并且由IRI强制执行)标准)是UTF-8。 %C3%84
是UTF-8中Ä
的正确编码。
不幸的是,在IRI出现之前,ATL是一个令人伤心的旧图书馆。当它看到非ASCII转义序列时,它会使用您机器的特定于语言环境的默认(ANSI)代码页将它们解码为Unicode,该代码页永远不会是UTF-8。对于西欧Windows安装,您可以获得代码页1252,其中%C3%84
表示两个字符Ä
。
(这可能是一个错误。在atlutil.h的版本中,我必须提到前面的评论说无论使用什么编码都没关系,因为没有非ASCII字符,这是真的对于上面AtlEscapeUrl
中的代码,它不经意地被复制粘贴,但对于AtlUnescapeUrl
来说根本不是真的。这似乎意味着ATL转义和unescape函数不使用相同的编码和所以不要往返......哎呀。)
要解决此问题,您可以自己执行Unicode位。而不是调用AtlUnescapeUrl
的Unicode(LPWSTR)版本,使用UTF-8编码(MultiByteToWideChar
CP_UTF8)将输入的Unicode字符串转换为字节字符串,然后调用{的字节(LPSTR)版本{ {1}}在字节字符串上,再次解码(AtlUnescapeUrl
CP_UTF8)。
或者选择另一个较少损坏的URL处理库。