![](/img/trans.png)
[英]Javascript encodeURI() vs. PHP rawurldecode() and special characters
[英]Using encodeURI() vs. escape() for utf-8 strings in JavaScript
我在 JavaScript 中处理 utf-8 字符串,需要对它们进行转义。
escape() / unescape() 和 encodeURI() / decodeURI() 都在我的浏览器中工作。
逃脱()
> var hello = "안녕하세요"
> var hello_escaped = escape(hello)
> hello_escaped
"%uC548%uB155%uD558%uC138%uC694"
> var hello_unescaped = unescape(hello_escaped)
> hello_unescaped
"안녕하세요"
编码URI()
> var hello = "안녕하세요"
> var hello_encoded = encodeURI(hello)
> hello_encoded
"%EC%95%88%EB%85%95%ED%95%98%EC%84%B8%EC%9A%94"
> var hello_decoded = decodeURI(hello_encoded)
> hello_decoded
"안녕하세요"
但是, Mozilla 表示不推荐使用 escape() 。
尽管 encodeURI() 和 decodeURI() 使用上述 utf-8 字符串,但文档(以及函数名称本身)告诉我这些方法用于 URI; 我没有看到任何地方提到的 utf-8 字符串。
简单地说,utf-8 字符串可以使用 encodeURI() 和 decodeURI() 吗?
你好!
当谈到escape
和unescape
,我遵循两条规则:
正如问题中提到的, escape
和unescape
都已被弃用。 一般来说,应该避免使用不推荐使用的函数。
所以,如果encodeURIComponent
或encodeURI
对你有用,你应该使用它而不是escape
。
浏览器将尽可能努力实现向后兼容。 所有主流浏览器都已经实现了escape
和unescape
; 他们为什么要取消实施它们?
如果新规范要求浏览器重新定义escape
和unescape
,他们将不得不这样做。 可是等等! 编写规范的人非常聪明。 他们也有兴趣不破坏向后兼容性!
我意识到上述论点是薄弱的。 但是请相信我,......当涉及到浏览器时,不推荐使用的东西是有效的。 这甚至包括不推荐使用的 HTML 标签,例如<xmp>
和<center>
。
escape
和unescape
: 那么自然地,下一个问题是,什么时候使用escape
或unescape
?
最近,在处理CloudBrave 时,我不得不处理utf8
、 latin1
和相互转换。
在阅读了一堆博客文章后,我意识到这是多么简单:
var utf8_to_latin1 = function (s) {
return unescape(encodeURIComponent(s));
};
var latin1_to_utf8 = function (s) {
return decodeURIComponent(escape(s));
};
这些不使用escape
和unescape
相互转换相当复杂。 通过不避免escape
和unescape
,生活变得更简单。
希望这可以帮助。
Mozilla 说不推荐使用 escape() 。
是的,你应该避免同时使用escape()
和unescape()
简单地说,utf-8 字符串可以使用 encodeURI() 和 decodeURI() 吗?
是的,但根据您输入的形式和所需的输出形式,您可能需要一些额外的工作。
根据您的问题,我假设您有一个 JavaScript 字符串,并且您想将编码转换为 UTF-8,并最终以某种转义形式存储该字符串。
首先需要注意的是,JavaScript 字符串编码是 UCS-2,类似于 UTF-16,不同于 UTF-8。
请参阅: https : //mathiasbynens.be/notes/javascript-encoding
encodeURIComponent()
非常适合这项工作,因为它将 UCS-2 JavaScript 字符串转换为 UTF-8,并以%nn
子字符串序列的形式对其进行转义,其中每个nn
是每个字节的两个十六进制数字。
但是encodeURIComponent()
不会转义 ASCII 范围内的字母、数字和其他一些字符。 但这很容易解决。
例如,如果要将 JavaScript 字符串转换为表示原始字符串 UTF-8 编码的字节的数字数组,则可以使用此函数:
//
// Convert JavaScript UCS2 string to array of bytes representing the string UTF8 encoded
//
function StringUTF8AsBytesArrayFromString( s )
{
var i,
n,
u;
u = [];
s = encodeURIComponent( s );
n = s.length;
for( i = 0; i < n; i++ )
{
if( s.charAt( i ) == '%' )
{
u.push( parseInt( s.substring( i + 1, i + 3 ), 16 ) );
i += 2;
}
else
{
u.push( s.charCodeAt( i ) );
}
}
return u;
}
如果要将字符串转换为十六进制表示:
//
// Convert JavaScript UCS2 string to hex string representing the bytes of the string UTF8 encoded
//
function StringUTF8AsHexFromString( s )
{
var u,
i,
n,
s;
u = StringUTF8AsBytesArrayFromString( s );
n = u.length;
s = '';
for( i = 0; i < n; i++ )
{
s += ( u[ i ] < 16 ? '0' : '' ) + u[ i ].toString( 16 );
}
return s;
}
如果将 for 循环中的行更改为
s += '%' + ( u[ i ] < 16 ? '0' : '' ) + u[ i ].toString( 16 );
(在每个十六进制数字前添加%
符号)
可以使用decodeURIComponent()
将生成的转义字符串(UTF-8 编码)转回 JavaScript UCS-2 字符串
永远不能使用encodeURI()
或encodeURIComponent()
。 让我们试试看:
console.log(encodeURIComponent('@#*'));
输入: @#*
。 输出: %40%23*
。 等等,那么, *
字符到底发生了什么? 怎么没转化? 想象一下:您询问用户要删除哪个文件,他们的回答是*
。 服务器端,您使用encodeURIComponent()
转换它,然后运行rm *
。 好吧,有消息告诉您:使用encodeURIComponent()
意味着您刚刚删除了所有文件。
使用fixedEncodeURI()
,当尝试编码完整的 URL(即所有example.com?arg=val
)时,如MDN encodeURI() 文档中定义和进一步解释的那样......
function fixedEncodeURI(str) { return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']'); }
或者,您可能需要使用fixedEncodeURIComponent()
,当尝试编码 URL 的一部分(即example.com?arg=val
的arg
或val
)时,如MDN encodeURIComponent() 文档中定义和进一步解释的那样...
function fixedEncodeURIComponent(str) { return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { return '%' + c.charCodeAt(0).toString(16); }); }
如果根据上面的描述你无法区分它们,我总是喜欢将其简化为:
fixedEncodeURI()
:不会将+@?=:#;,$&
编码为其 http 编码的等价物(因为&
和+
是常见的 URL 运算符)fixedEncodeURIComponent()
会将+@?=:#;,$&
编码为它们的 http 编码等价物。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.