escape()
是在 B.2.1.2 escape 章节中定义的,而 Annex B 的介绍文本 中提到:
... 这个附录中指定的所有语言特性和行为都有一个或多个不良特征,在没有遗留使用情况的情况下,将从本规范中删除...
对于代码单元值小于等于 0xFF 的字符,escape()
会生成一个两位数的转义序列:%xx
。这基本上意味着,escape()
会使用 latin-1 编码,将仅包含来自 U+0000
到 U+00FF
字符的字符串转换为百分号编码字符串。
对于代码单元值大于的字符,将使用四位数格式%uxxxx
。这在 mailto:
-URI(如 RFC6068 中定义的那样)中的 hfields
部分(存储主题和正文)不允许使用。
mailtoURI = "mailto:" [ to ] [ hfields ]
to = addr-spec *("," addr-spec )
hfields = "?" hfield *( "&" hfield )
hfield = hfname "=" hfvalue
hfname = *qchar
hfvalue = *qchar
...
qchar = unreserved / pct-encoded / some-delims
some-delims = "!" / "$" / "'" / "(" / ")" / "*"
/ "+" / "," / ";" / ":" / "@"
unreserved
和pct-encoded
在STD66中有定义:
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded = "%" HEXDIG HEXDIG
只有当百分号直接后面跟着两个十六进制数字时才允许使用百分号,不允许使用百分号后跟 u
。
使用一个自己实现的版本,它的行为与escape
完全相同,并不能解决任何问题——相反,继续使用escape
,因为它不会很快被移除。
总之:如果所有字符都在范围U+0000
到U+00FF
之间,则您以前对escape()
的使用会生成拉丁1百分比编码的mailto-URI,否则会生成无效的URI(如果某些应用程序考虑了javascript-encode/decode兼容性,则可能仍然可以正确解释它们)。
使用encodeURIComponent()
生成UTF8百分比编码的mailto-URI更加准确(没有创建无效URI的风险),并且具有未来的可靠性(不要使用encodeURI()
,它不会转义?
、/
等)。RFC6068在许多地方要求使用UTF-8(但允许在组成的电子邮件消息中使用其他编码)。
例如:
text_latin1="Swedish åäö"
text_other="Emoji "
document.getElementById('escape-latin-1-link').href="mailto:?subject="+escape(text_latin1);
document.getElementById('escape-other-chars-link').href="mailto:?subject="+escape(text_other);
document.getElementById('utf8-link').href="mailto:?subject="+encodeURIComponent(text_latin1);
document.getElementById('utf8-other-chars-link').href="mailto:?subject="+encodeURIComponent(text_other);
function mime_word(text){
q_encoded = encodeURIComponent(text)
.replace(/[_!'()*]/g, function(c){return '%'+c.charCodeAt(0).toString(16).toUpperCase();})
.replace(/%20/g,'_')
.replace(/%/g,'=');
return encodeURIComponent('=?utf-8?Q?'+q_encoded+'?=');
}
document.getElementById('mime-word-link').href="mailto:?subject="+mime_word(text_latin1);
document.getElementById('mime-word-other-chars-link').href="mailto:?subject="+mime_word(text_other);
<a id="escape-latin-1-link">escape()-latin1</a><br/>
<a id="escape-other-chars-link">escape()-emoji</a><br/>
<a id="utf8-link">utf8</a><br/>
<a id="utf8-other-chars-link">utf8-emoji</a><br/>
<a id="mime-word-link">mime-word</a><br/>
<a id="mime-word-other-chars-link">mime-word-emoji</a><br/>
对我来说,在Thunderbird中,UTF-8链接和Mime-Word链接都可以正常工作。只有纯文本的UTF-8链接可以在Windows 10内置的Mailapp和最新版本的Outlook中正常工作。
utf-8
吗? - Cyclonecode