为啥不 decodeURI("a+b") == "a b"?

Posted

技术标签:

【中文标题】为啥不 decodeURI("a+b") == "a b"?【英文标题】:Why doesn't decodeURI("a+b") == "a b"?为什么不 decodeURI("a+b") == "a b"? 【发布时间】:2011-05-30 22:26:17 【问题描述】:

我正在尝试在 Ruby 中对 URL 进行编码并使用 javascript 对其进行解码。然而,加号给了我奇怪的行为。

在 Ruby 中:

[Dev]> CGI.escape "a b"
=> "a+b"
[Dev]> CGI.unescape "a+b"
=> "a b"

到目前为止一切顺利。但是 Javascript 呢?

>>> encodeURI("a b")
"a%20b"
>>> decodeURI("a+b")
"a+b"

基本上我需要一种在 Javascript 和 Ruby 中工作方式相同的编码/解码 URL 的方法。

编辑:decodeURIComponent 也好不到哪里去:

>>> encodeURIComponent("a b")
"a%20b"
>>> decodeURIComponent("a+b")
"a+b"

【问题讨论】:

【参考方案1】:

如果您使用 php urlencode,则在通过 XMLHttpRequest 从 php 发送响应时也会遇到相同的 a+b 问题。要解决它,您必须使用 php rawurlencode 函数。

由于某种原因,从 XMLHttpRequest 到 php urldecode 工作正常。

【讨论】:

这个答案如何解决这个问题?它询问的是 JavaScript 和 Ruby,而不是 PHP。【参考方案2】:

您可能想查看URI.encodeURI.decode

require 'uri'

URI.encode('a + b') # => "a%20+%20b"
URI.decode('a%20+%20b') # => "a + b"

另一个我经常使用的替代品是Addressable::URI

require 'addressable/uri'
Addressable::URI.encode('a + b') #=> "a%20+%20b"
Addressable::URI.unencode('a%20+%20b') #=> "a + b"

【讨论】:

好的,很好!有任何理由曾经使用CGI.escape吗? (或者它只是为了欺骗我!) 另外,请注意 URI.encode 已弃用:***.com/questions/2824126/… @Horace Loeb,然后使用 Addressable::URI。 URI.(un)escape deprecated? 讨论决定。 Addressable::URI 看起来很酷,但是离开标准库的开销太大了。我会选择URI.encode【参考方案3】:

+ 不被视为空格。一种解决方法是将+ 替换为%20,然后调用decodeURIComponent

取自 php.js'urldecode:

decodeURIComponent((str+'').replace(/\+/g, '%20'));

【讨论】:

'+' 是查询中空间编码的内容。请参阅URL encoding 中的最后一句话。它与 URL 参数中的空格不同,后者将编码为“%20”。 谢谢。您的解码工作正常。还有一个问题。您能否解释一下为什么加号不被视为空格? @VictorYarema 我不能告诉你它是怎么变成这样的。但问题是查询字符串被认为是application/x-www-form-urlencoded - not URI。并且那个 MIME 有一条规则说空格必须编码为+。相关栏目:w3.org/TR/html401/interact/forms.html#h-17.13.4.1【参考方案4】:

From MDC decodeURI:

不解码无法由 encodeURI 引入的转义序列。

From MDC encodeURI:

请注意,encodeURI 本身无法形成正确的 HTTP GET 和 POST 请求,例如 XMLHTTPRequests,因为“&”、“+”和“=”未编码

【讨论】:

以上是关于为啥不 decodeURI("a+b") == "a b"?的主要内容,如果未能解决你的问题,请参考以下文章

为啥python运行不了?

java中为啥Integer和String的“==”判断方式不一样

为啥 "map! <C-q> :q <CR> " 在 vi​​m 中不起作用?

【求解】为啥会陷入死循环?

为啥我不能拥有带有此签名的 Q_PROPERTY?

"{"A":"5","B":"4","C":"3","D&q