用变音符号(带重音的字母)表示 URI 的正确方法是什么?

What is the proper way of denoting URI with diacritics (letters with accents)?

提问人:Marcos Camargo 提问时间:9/11/2016 最后编辑:unorMarcos Camargo 更新时间:9/12/2016 访问量:708

问:

在 URI 中使用变音符号的正确和官方方式是什么?

我有 3 种不同的方法如下所示:

  1. 这里 = , = , 空格 = , 逗号 = ,但此链接无法正常工作,因为字符被破坏了:á%E1â%E2%20%2C

    http://www.recordspreservation.org/cgi-bin/list_directory_1.cgi?directory=%2CBrasil%2CGoi%E1s%2CLuzi%E2nia%2CSanta%20Luzia%2CBatismos%201749-1753%2CImagens&image_name=_MG_5229.JPG
    
  2. 这里空格 = ,逗号 = 我没有对 a 做任何事情。此链接有效:%20%2C

    http://www.recordspreservation.org/cgi-bin/list_directory_1.cgi?directory=%2CBrasil%2CGoiás%2CLuziânia%2CSanta%20Luzia%2CBatismos%201749-1753%2CImagens&image_name=_MG_5229.JPG
    
  3. 这里空格 = ,逗号 = 我没有对 a 做任何事情。此链接有效:+%2C

    http://www.recordspreservation.org/cgi-bin/list_directory_1.cgi?directory=%2CBrasil%2CGoiás%2CLuziânia%2CSanta+Luzia%2CBatismos+1749-1753%2CImagens&image_name=_MG_5229.JPG
    
Perl URI URL 编码 变音符号

评论

0赞 Marcos Camargo 9/11/2016
我正在使用 uri_escape,当我使用 uri_escape_utf 时,我得到了这个有效的 URI。没有元音逃逸的那些更清晰。官方的做法是什么?recordspreservation.org/cgi-bin/......
1赞 Borodin 9/11/2016
如果我的回答不清楚,我很抱歉。所有这些都在 RFC 3986 中进行了描述,这证实了我在下面写的内容。正式地,URL 只能使用 7 位 ASCII 的受限子集,其他任何内容都必须进行百分比编码。如果需要使用 7 位 ASCII 之外的字符,则该字符必须采用 UTF-8 编码,并且生成的字节必须采用百分比编码。听起来你有一个允许你打破规则的服务器,我无法知道新的限制性较低的规则是什么,但你不应该依赖任何超出标准的东西。

答:

3赞 Borodin 9/11/2016 #1

URL 字符串中的字符必须位于 7 位 ASCII 的受限子集中,并且未为宽字符指定编码

其中一些集合是无保留的,可以在语法允许的任何地方使用

其余字符是保留的,因为它们构成了 URL 语法的一部分;如果保留字符在其语法含义之外使用,则必须对其进行百分比编码

既不属于保留类别也不属于非保留类别的 8 位字符必须始终采用百分比编码

##Unreserved 字符

0 to 9
A to Z
a to z
-
.
_
~

##Reserved 字符

! - %21
# - %23
$ - %24
& - %26
' - %27
( - %28
) - %29
* - %2A
+ - %2B
, - %2C
/ - %2F
: - %3A
; - %3B
= - %3D
? - %3F
@ - %40
[ - %5B
] - %5D

此链接无法正常工作,因为字符被破坏了

这是客户端和服务器之间的问题。看起来您正在发送 ISO-8859-1 字符,其中 scheme 和 对应于 e acutee circumflex。但是,如果您的服务器需要 UTF-8 编码,那么这些编码应该显示为字节序列和E1E2C3 A1C3 A2

我无法判断您的服务器期望什么编码,但这显然不是您要发送的。目前的标准是用 UTF-8 对非 ASCII 字符进行编码,并对生成的字节进行百分比编码



###Update

最好的解决方案是使用 URI 模块,该模块将根据需要对字符串进行编码

需要特别注意的是,如果您需要在源代码中使用 UTF-8 编码的字符,如下所示,那么您必须在程序顶部使用 utf8。您还需要确保您的编辑器正在将 UTF-8 数据写入程序文件。

use utf8;
use strict;
use warnings 'all';
use feature 'say';

use URI;

my $url = URI->new('http://www.recordspreservation.org/cgi-bin/list_directory_1.cgi?directory=,Brasil,Goiás,Luziânia,Santa Luzia,Batismos 1749-1753,Imagens&image_name=_MG_5229.JPG');

say $url;

###output

http://www.recordspreservation.org/cgi-bin/list_directory_1.cgi?directory=,Brasil,Goi%C3%A1s,Luzi%C3%A2nia,Santa%20Luzia,Batismos%201749-1753,Imagens&image_name=_MG_5229.JPG

评论

0赞 Marcos Camargo 9/11/2016
带有口音的字母似乎无需编码即可工作。这是可以接受的吗?我期待 UTF8 数据,这是我的问题。我应该发送 UTF8。
0赞 Borodin 9/11/2016
我想我需要看看你的代码。如果服务器需要 UTF-8,并且您的编辑器正在生成和显示 UTF-8,但您在程序顶部没有适当的位置,这可能会起作用。use utf8
0赞 Borodin 9/11/2016
正式地,除 7 位 ASCII 之外的任何内容在 URL 中都是非法的
0赞 Borodin 9/11/2016
@MarcosCamargo:请注意我的回答的更新。
0赞 Marcos Camargo 9/11/2016
好的,谢谢。我将使用 URI 模块并避免使用非 7 位 ASCII。