是否应该在mailto:超链接中进行编码?


39

mailto超链接中放置带有地址标签(又称子地址)的电子邮件地址时

<a href="mailto:username+foo@example.com">mail us now!</a>

…电子邮件中的加号应使用URL编码吗?

<a href="mailto:username%2Bfoo@example.com">mail us now!</a>

我无法弄清楚,文档相互冲突。我们在现实世界中的测试也产生了不同的结果,从而使结果更加混乱。


您能否更详细地说明实际测试的方法和结果?某些电子邮件客户端/服务是否正确处理而其他人则感到窒息?你可以说得更详细点吗?
布赖森

1
@bryson我知道“使用gmail发送” chrome扩展程序在mailto中存在未编码加号的问题:例如,但这也许是一个错误。
Jeff Atwood

2
只需使用适用于chrome的任何一种即可。
Hardwareguy

Answers:


22

加号用于编码URL中的空格,而不是HTML和SMTP(RFC2821)中的空格。但是,由于mailto:address@server.com是URI(具有协议,协议分隔符和协议地址),因此应将其视为URI,并且应进行百分比编码

因此,由客户端来准确地解析编码的表示并将其解码为适当的程度。这是微软对此事的正式看法

您应该在mailto上应用URL编码:如果电子邮件地址中的字符保留URI,则嵌入HTML中的URL。这样可以确保您做正确的事。客户端应从接收URI的位置适当地对其进行解码。是的,这this+address@gmail.com是一封非常有效的电子邮件;是this%2Baddress@gmail.com也有效。是的,这两个是不同的,但是是否要区别对待取决于客户...

如前所述,并非所有客户端都能正确呈现此图像。我建议找到用户将使用的最有可能的客户端(gmail?基于浏览器的客户端?Outlook?),并执行该客户端的操作。您说您在GMail上测试过?您是如何测试的?使用“基于浏览器的mailto:客户端(例如,firefox和gmail产品的附加组件),URI很有可能不会被解码(应该如此)。


有人在何处有效有任何实际数据吗?
Wez Furlong

好吧,我确实对Microsoft确认的工作做了具体说明……
jcolebrand 2011年

这是现场。Gmail无法正确处理它们,但是由于Google忽略了用户错误报告,因此您无能为力。
马修(Matthew)

5
如果您使用+URI 编码,则@还需要进行编码,因为它也是保留字符。如果仔细阅读RFC,就会发现不透明部分+是合法的。
尤金·横田

我可能是错的,但不是保留将用户名与主机分开(例如example@example.com/path)吗?然后它将在地址中占据一席之地,因为它确实将用户名与主机分开。
Maciej Piechotka 2011年

8

您可以编码+,但不必这样做。

首先,我们需要同意这mailtoRFC 2396指定的通用URI的示例。(这就是XHTML和HTML 4的用途)。

现在让我们找出RFC 2396中的保留字符列表。

reserved    = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
              "$" | ","

URI分为绝对和相对:

URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]

并且由于mailto:指定了scheme,因此这是绝对URI:

absoluteURI   = scheme ":" ( hier_part | opaque_part )

而且,由于这两种模式的hier_part开头/mailto是一个不透明的部分。

opaque_part   = uric_no_slash *uric

uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
                "&" | "=" | "+" | "$" | ","

uric          = reserved | unreserved | escaped

因此,限制在于,/如果涉及第一个字符,则必须转义,但是之后您可以放入保留字符,包括+@

这是另一个支持此功能的RFC。在2010年发布的最新mailto方案RFC RFC 6068中,它表示:

'mailto'同样,创建URI的软件也必须小心以对使用的所有保留字符进行编码。HTML表单是一种创建'mailto'URI 的软件。当前的实现将空格编码为'+',但这会产生问题,因为'+'无法'+''mailto' URI 中将这种空格与实数区分开。产生'mailto'URI时,所有空格都应编码为 %20'+'字符可以编码为%2B。请注意,'+' 字符通常用作电子邮件地址的一部分,以指示子地址,例如中的<bill+ietf@example.org>


我对该语法并不完全熟悉,但是它列出了与未保留池分开的字符,这表明+是保留字符。它并不表示必须对其进行编码。微软表示要对其进行编码。C'est la vie,我拭目以待。
jcolebrand 2011年

1
如果部分不以开头/,则+不再成为保留字符。
Eugene Yokota

我不同意。“电子邮件地址”的定义非常特殊,首先必须谨慎处理。该标准非常令人困惑。幸运的是,我们在这里不同意。
jcolebrand 2011年

8

严格阅读相关RFC表示,应对“ +”进行编码。

http://tools.ietf.org/html/rfc2368上第 2页顶部的第2节说:

“请注意,必须对“至”中的所有URL保留字符进行编码:尤其是括号,逗号和百分号(“%”),它们通常以“邮箱”语法出现。

URI的RFC(http://tools.ietf.org/html/rfc3986#section-2.2)列出了“ +”作为保留字符。

就是说,“正确”并不一定适用于所有浏览器。显然,某些浏览器将始终将正确的事情视为错误,将错误的事情视为正确。

编辑:至于RFC6068及其“ MAY”,我将其视为上下文相关。如果您正在编写用于文本阅读的URL,则“ +”会更有意义,但是,如果您以HTML编写,则对RFC3986的更严格解释将更符合“有效HTML”的想法,因此,使用该值的任何事物都应期望它被编码。


2
在RFC 3986中,mailto将被视为path-rootless,它允许使用pchar定义序列(unreserved / pct-encoded / sub-delims / ":" / "@")+是的一部分sub-delims。因此严格的阅读说+不需要百分比编码。
Eugene Yokota


3

我认为无论编码与否,都不会带来真正的改变。问题是邮件客户端。例如,Yahoo Mail仅将连字符用于子地址,而gMail使用加号。

那是我的2美分...

编辑:下面的响应有一个重点。


是的,没错,电子邮件子寻址存在一些差异-但在这种情况下,电子邮件是gmail托管的,因此我知道加号是正确的,并且假设服务器通过客户端接收到邮件,那么在服务器收到邮件后,它们就会起作用。
Jeff Atwood

问题是应用程序解析URI请求。如果它希望接收URLEncoded数据,则它将解码数据,但这对您(错误编码)或客户端(进行假设)都不公平。协议没有规定预期的编码,客户端则有规定。看到我对@Wez对A所做的进一步编辑
jcolebrand 2011年

3

RFC1738

3.5。马利托

mailto URL方案用于指定个人或服务的Internet邮件地址。除Internet邮件地址外,没有其他任何其他信息。

mailto URL的形式为:

    mailto:<rfc822-addr-spec>

RFC 822所述,addr-spec的编码在哪里。在mailto URL中,没有保留字符。

请注意,百分号(“%”)通常在RFC 822地址中使用,并且必须进行编码。

与许多URL不同,mailto方案并不表示要直接访问的数据对象。它没有指定对象的意义。它的用途与MIME中的message / external-body类型不同。

由于没有保留字符,因此应对其进行编码。


并根据tools.ietf.org/html/rfc6068 “在生成“ mailto” URI时,所有空格均应编码为%20,而'+'字符应编码为%2B”
Jeff Atwood

1
Since there are no reserved characters it should be encoded.嗯,这没有任何意义。
jcolebrand 2011年

@jcolebrand'+'是URL方案中的特殊字符,因此在没有特殊作用时必须进行编码-即。不保留时。
S.Skov 2011年

@Jeff确实-我对生活在旧的RFC世界中很不好。然后,tools.ietf.org/html/rfc2119基本上会告诉您去做自己认为最适合的事情。
S.Skov 2011年

似乎……在精神上与我最初阅读说明的方式背道而驰。
jcolebrand 2011年

3

根据答案中提到的RFC 6068,您可以将加号编码为%2B

造成混淆的原因是,将空格转换为加号实际上并不是标准网址编码的一部分,而是形式参数编码(即application/x-www-form-urlencoded)的一部分

就像PHP rawurlencode()和的区别urlencode()

因此,RFC 6068所说的是,mailto:URL应该使用“原始”标准URL编码(根据RFC 3986),并且出现在URL中的加号应始终被视为文字加号,而不是被视为具有空格的被表单编码。

如果本地客户端确实将加号转换为空格,则表示它已损坏。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.