javascript - javascript转义的替代品?

标签 javascript encoding escaping mailto

我知道 escape函数已被弃用,您应该改用 encodeURI 或 encodeURIComponent。但是,encodeUri 和 encodeUriComponent 的作用与转义不同。

我想用瑞典语 åäö 在 javascript 中创建一个 mailto 链接。以下是 escape、encodeURIComponent 和 encodeURI 之间的比较:

var subject="åäö";
var body="bodyåäö";

console.log("mailto:?subject="+escape(subject)+"&body=" + escape(body));
console.log("mailto:?subject="+encodeURIComponent(subject)+"&body=" + encodeURIComponent(body));
console.log("mailto:?subject="+encodeURI(subject)+"&body=" + encodeURI(body));  

Output:
mailto:?subject=My%20subject%20with%20%E5%E4%F6&body=My%20body%20with%20more%20characters%20and%20swedish%20%E5%E4%F6
mailto:?subject=My%20subject%20with%20%C3%A5%C3%A4%C3%B6&body=My%20body%20with%20more%20characters%20and%20swedish%20%C3%A5%C3%A4%C3%B6
mailto:?subject=My%20subject%20with%20%C3%A5%C3%A4%C3%B6&body=My%20body%20with%20more%20characters%20and%20swedish%20%C3%A5%C3%A4%C3%B6 

只有使用“escape”创建的 mailto 链接才能使用 IE 或 Chrome 在 Outlook 中打开格式正确的邮件。使用 encodeURI 或 encodeURIComponent 时,主题说:

My subject with åäö

而且 body 看起来也很乱。

除了 escape 之外,还有其他一些函数可以用来获取有效的 mailto 链接吗?

最佳答案

escape()B.2.1.2 escape 节中定义和 introduction text of Annex B说:

... All of the language features and behaviours specified in this annex have one or more undesirable characteristics and in the absence of legacy usage would be removed from this specification. ...

对于代码单元值为 0xFF 或更小的字符,escape() 生成一个两位数的转义序列:%xx。这基本上意味着,escape() 将仅包含从 U+0000U+00FF 的字符的字符串转换为使用百分比编码的字符串latin-1 编码。

对于具有更大代码单元的字符,使用四位数格式%uxxxx。这在 mailto 的 hfields 部分(存储主题和正文的地方)是不允许的:-URI(在 RFC6068 中定义):

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  = "!" / "$" / "'" / "(" / ")" / "*"
               / "+" / "," / ";" / ":" / "@"

unreservedpct-encodedSTD66 中定义:

unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded   = "%" HEXDIG HEXDIG

百分号仅在紧跟两个十六进制数字时才允许使用,百分号后跟 u 是不允许的。

使用自行实现的版本,其行为与 escape 完全相同并不能解决任何问题 - 而是继续使用 escape,它不会很快被删除.



总结一下:如果所有字符都在 U+0000 范围内,您之前使用 escape() 生成 latin1-percent-encoded mailto-URI U+00FF,否则会生成无效的 URI(如果某些应用程序考虑到 javascript-encode/decode 兼容性,它可能仍会被正确解释)。

使用 encodeURIComponent() 生成 UTF8-percent-encoded mailto-URI 更正确(没有创建无效 URI 的风险)和面向 future (不要使用 encodeURI (),它不会转义?, /, ...)。 RFC6068要求在许多地方使用 UTF-8(但允许对“MIME 编码的单词和撰写的电子邮件中的正文”使用其他编码)。

例子:

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) //to utf8 percent encoded
  .replace(/[_!'()*]/g, function(c){return '%'+c.charCodeAt(0).toString(16).toUpperCase();})// encode some more chars as utf8
  .replace(/%20/g,'_') // mime Q-encoding is using underscore as space
  .replace(/%/g,'='); //mime Q-encoding uses equal instead of percent
  return encodeURIComponent('=?utf-8?Q?'+q_encoded+'?=');//add mime word stuff and escape for uri
}

//don't use mime_word for body!!!
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/>

对我来说,UTF-8 链接和 Mime-Word 链接在 Thunderbird 中有效。只有纯 UTF-8 链接适用于 Windows 10 内置 Mailapp 和我最新版本的 Outlook。

关于javascript - javascript转义的替代品?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26342123/

相关文章:

javascript - 安装 Android 6.0.1 后,应用程序在调试时崩溃

ios - 带有 Alamofire 4 正文数据的 POST 请求

video - bsf过滤器有什么区别? (ffmpeg)

java - 如何正确为带有转义字符的 String.matches() 创建正则表达式?

c# - 是否可以在没有转义序列的情况下在字符串中输入换行符?

javascript - 使用 AJAX JSON 进行 jQuery 自动完成

javascript - ASP.NET MVC 将 JavaScript 应用到所有类

Javascript 扩展原型(prototype)和 for-in

android - Webview中的字符串编码问题

html - 带方括号的编码 URL。 Chrome/Firefox/IE 中的不同行为