我正在尝试对电子邮件地址进行一些最小的非常小的验证,尽管看到很多建议反对这样做。我这样做的原因是我正在实现的规范要求电子邮件地址采用这种格式:
mailto:<uri-encoded local part>@<domain part>
我想简单地分开起始mailto:
和最后@
,并假设“本地部分”介于这些之间。我将验证“本地部分”是否为URI编码。
我不想做更多的事情,并且规范允许我为大部分内容“尽力而为”验证,但是在URI编码和mailto:
上非常具体前缀。
从我读过的所有内容中,分析@
对我来说似乎有风险。
我在网上和Stack Overflow上看到了许多相互矛盾的建议,其中大部分都是“读取RFC”,有些人说域名部分只能是某些字符,即{{1 }} 1-9
a-z
A-Z
,可能是其他几个角色,但不多于此。 E.g:
当我在域名上阅读各种RFC时,我发现允许使用"any CHAR" (dtext
)或"any character between ASCII 33 and 90" (dtext
),这意味着允许使用-.
个符号。由于"comments" are allowed in parens (
)
and can contain characters between ASCII 42 and 91包括@
。
RFC1035 seems to support the letters+digits+dashes+periods requirement,但"domain literal" syntax in RFC5322似乎允许更多字符。
我是否误解了RFC,或者我是否遗漏了一些不允许在电子邮件地址的域名部分中@
的内容? “域文字”语法是否我不必担心?
答案 0 :(得分:2)
互联网上最新的电子邮件RFC是RFC 5322,它专门针对地址。
addr-spec = local-part "@" domain
local-part = dot-atom / quoted-string / obs-local-part
点原子是规范中定义的高度受限制的字符集。但是,quoted-string
是您遇到麻烦的地方。它并不经常使用,但就你遇到它的可能性而言,你很可能会在引号中找到一些本身可以包含@
字符的东西。
但是,如果您从最后一个@
中拆分字符串,则应该安全地找到local-part
和domain
,这在规范中已根据您的方式明确定义可以验证它。
问题来自punycode,几乎任何Unicode字符都可以映射到有效的DNS名称。如果你是前端的系统可以理解和解释punycode,那么你必须处理几乎任何有效的unicode字符的东西。如果你知道你不打算使用punycode,那么你可以使用一个更受限制的集合,通常是字母,数字和连字符。
引用已故的,伟大的Jon Postel: TCP实现应该遵循健壮性的一般原则:保守你所做的事情,对你接受别人的事情要宽容。
本地部分的旁注: 当然,请记住,互联网上可能有很多系统不需要严格遵守规范,因此可能允许规范之外的事情由于长期的自由接受/保守传输而工作理念。