更换javascript转义?

gus*_*per 9 javascript mailto encoding escaping

我知道转义函数已被弃用,你应该使用encodeURI或encodeURIComponent.但是,encodeUri和encodeUriComponent与escape不同.

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

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 
Run Code Online (Sandbox Code Playgroud)

只有使用"转义"创建的mailto链接才能使用IE或Chrome在Outlook中打开格式正确的邮件.当使用encodeURI或encodeURIComponent时,主题说:

My subject with åäö
Run Code Online (Sandbox Code Playgroud)

身体也看起来搞砸了.

还有其他一些功能,除了我可以用来获取工作mailto链接吗?

T S*_*T S 5

escape()B.2.1.2节中定义了转义,附件 B介绍文本说:

... 本附件中指定的所有语言特性和行为都有一个或多个不受欢迎的特征,如果没有遗留用法,将从本规范中删除。...

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

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

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

unreservedpct-encodedSTD66中定义:

unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded   = "%" HEXDIG HEXDIG
Run Code Online (Sandbox Code Playgroud)

百分号只允许在它后面直接跟两个十六进制数字,百分比后面u是不允许的。

使用自我实现的版本,它的行为就像escape不能解决任何问题一样 - 而是继续使用escape,它不会很快被删除。



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

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

例子:

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  = "!" / "$" / "'" / "(" / ")" / "*"
               / "+" / "," / ";" / ":" / "@"
Run Code Online (Sandbox Code Playgroud)
unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded   = "%" HEXDIG HEXDIG
Run Code Online (Sandbox Code Playgroud)

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


Hol*_*ger 5

直接引用MDN文档...

\n
\n

此函数主要用于 URL 查询(URL 中 ? 后面的部分)\xe2\x80\x94,而不是用于转义普通字符串文字,其使用格式“\\xHH”。(HH 是两个十六进制数字,形式 \\xHH\\xHH 用于更高平面的 Unicode 字符。)

\n
\n

您遇到的问题是因为escape()不支持 UTF-8 whileencodeURI()encodeURIComponent()do。

\n

但要绝对明确永远不要使用encodeURI()or encodeURIComponent() 让我们尝试一下:

\n

\r\n
\r\n
console.log(encodeURIComponent(\'@#*\'));
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n

输入:@#*。输出:%40%23*。通常,一旦用户输入被清理,我觉得我可以信任经过清理的输入。但是,如果我rm *在 Linux 系统上运行来删除用户指定的文件,那么实际上会删除系统上的所有文件,即使我 100% 完全在服务器端进行编码。encodeURI()这是和中的一个巨大错误encodeURIComponent(),MDN Web 文档明确指出了解决方案。

\n

fixedEncodeURI()当尝试编码完整的 URL(即所有 )时,请使用example.com?arg=val, ,如MDNencodeURI() 文档中的定义和进一步解释...

\n
\n
function fixedEncodeURI(str) {\n   return encodeURI(str).replace(/%5B/g, \'[\').replace(/%5D/g, \']\');\n}\n
Run Code Online (Sandbox Code Playgroud)\n
\n

fixedEncodeURIComponent()或者,当尝试对 URL 的一部分(即 thearg或 the valin )进行编码时,您可能需要使用 use example.com?arg=val,如MDNencodeURIComponent() 文档中的定义和进一步解释...

\n
\n
function fixedEncodeURIComponent(str) {\n return encodeURIComponent(str).replace(/[!\'()*]/g, function(c) {\n   return \'%\' + c.charCodeAt(0).toString(16);\n });\n}\n
Run Code Online (Sandbox Code Playgroud)\n
\n

如果你无法区分什么fixedEncodeURI()fixedEncodeURIComponent()什么和escape()做什么,我总是喜欢用以下方式简化它:

\n
    \n
  • fixedEncodeURI():不会编码+@?=:#;,$&为它们的 http 编码等效项(因为&+是常见的 URL 运算符)
  • \n
  • fixedEncodeURIComponent() 编码+@?=:#;,$&为其 http 编码的等效项。
  • \n
\n


Bas*_*ANI -8

escape() 函数在 JavaScript 1.5 版本中已被弃用。请改用encodeURI()encodeURIComponent()

例子

string:            "May/June 2016, Volume 72, Issue 3"
escape:            "May/June%202016%2C%20Volume%2072%2C%20Issue%203"
encodeURI:         "May/June%202016,%20Volume%2072,%20Issue%203"
encodeURIComponent:"May%2FJune%202016%2C%20Volume%2072%2C%20Issue%203"
Run Code Online (Sandbox Code Playgroud)

来源https://www.w3schools.com/jsref/jsref_escape.asp

  • 这两个函数与 escape 的作用不同。这个问题甚至指出了这一点。此外,W3 学校并不是一个很好的链接资源。 (6认同)