Html 为什么要对 %2B 字符串进行 urldecode?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18653252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is this %2B string being urldecoded?
提问by Yellowfog
[This may not be precisely a programming question, but it's a puzzle that may best be answered by programmers. I tried it first on the Pro Webmasters site, to overwhelming silence]
[这可能不完全是一个编程问题,但它是一个最好由程序员回答的难题。我首先在 Pro Webmasters 网站上尝试过,以压倒性的沉默]
We have an email address verification process on our website. The site first generates an appropriate key as a string
我们的网站上有电子邮件地址验证流程。该站点首先生成一个适当的密钥作为字符串
mykey
It then encodes that key as a bunch of bytes
然后将该密钥编码为一堆字节
&$dac~?????!
It then base64 encodes that bunch of bytes
然后 base64 编码那串字节
JiRkYWN+yoyIhIQ==
Since this key is going to be given as a querystring value of a URL that is to be placed in an HTML email, we need to first URLEncode it then HTMLEncode the result, giving us (there's no effect of HTMLEncoding in the example case, but I can't be bothered to rework the example)
由于此键将作为要放置在 HTML 电子邮件中的 URL 的查询字符串值给出,因此我们需要先对其进行 URLEncode,然后对结果进行 HTMLEncode,从而为我们提供(示例中 HTMLEncoding 没有效果,但是我懒得重新编写示例)
JiRkYWN%2ByoyIhIQ%3D%3D
This is then embedded in HTML that is sent as part of an email, something like:
然后将其嵌入作为电子邮件的一部分发送的 HTML 中,例如:
click <a href="http://myapp/verify?key=JiRkYWN%2ByoyIhIQ%3D%3D">here</a>.
Or paste <b>http://myapp/verify?key=JiRkYWN%2ByoyIhIQ%3D%3D</b> into your browser.
When the receiving user clicks on the link, the site receives the request, extracts the value of the querystring 'key' parameter, base64 decodes it, decrypts it, and does the appropriate thing in terms of the site logic.
当接收用户单击链接时,站点会收到请求,提取查询字符串“key”参数的值,base64 对其进行解码、解密,并根据站点逻辑执行相应的操作。
Howeveron occasion we have users who report that their clicking is ineffective. One such user forwarded us the email he had been sent, and on inspection the HTML had been transformed into (to put it in terms of the example above)
然而,有时我们会有用户报告他们的点击无效。一位这样的用户向我们转发了他发送的电子邮件,经过检查,HTML 已被转换为(根据上面的示例进行说明)
click <a href="http://myapp/verify?key=JiRkYWN+yoyIhIQ%3D%3D">here</a>
Or paste <b>http://myapp/verify?key=JiRkYWN+yoyIhIQ%3D%3D</b> into your browser.
That is, the %2B string - but none of the other percentage encoded strings - had been converted into a plus. (It's definitely leavingus with the right values - I've looked at the appropriate SMTP logs).
也就是说,%2B 字符串 - 但没有其他百分比编码的字符串 - 已转换为加号。(这肯定给我们留下了正确的值——我已经查看了相应的 SMTP 日志)。
key=JiRkYWN%2ByoyIhIQ%3D%3D
key=JiRkYWN+yoyIhIQ%3D%3D
So I think that there are a couple of possibilities:
所以我认为有两种可能性:
There's something I'm doing that's stupid, that I can't see, or
Some mail clients convert %2b strings to plus signs, perhaps to try to cope with the problem of people mistakenly URLEncoding plus signs
我正在做一些愚蠢的事情,我看不到,或者
一些邮件客户端将 %2b 字符串转换为加号,也许是为了应对人们误将 URLEncoding 加号的问题
In case of 1 - what is it? In case of 2 - is there a standard, known way of dealing with this kind of scenario?
在 1 的情况下 - 它是什么?在 2 的情况下 - 是否有一种标准的、已知的方法来处理这种情况?
Many thanks for any help
非常感谢您的帮助
回答by Vorsprung
The problem lies at this step
问题出在这一步
on inspection the HTML had been transformed into (to put it in terms of the example above)
经过检查,HTML 已被转换为(按照上面的示例进行说明)
click <a href="http://myapp/verify?key=JiRkYWN+yoyIhIQ%3D%3D">here</a>
Or paste <b>http://myapp/verify?key=JiRkYWN+yoyIhIQ%3D%3D</b> into
your browser.
That is, the %2B string - but none of the other percentage encoded strings - had been converted into a plus
也就是说,%2B 字符串 - 但没有其他百分比编码的字符串 - 已转换为加号
Your application at "the other end" must be missing a step of unescaping. Regardless of if there is a %2B or a + a function like perls uri_unescape returns consistent answers
您在“另一端”的应用程序必须缺少一个转义步骤。无论是否有 %2B 或 + 像 perls uri_unescape 这样的函数都会返回一致的答案
DB<9> use URI::Escape;
DB<10> x uri_unescape("JiRkYWN+yoyIhIQ%3D%3D")
0 'JiRkYWN+yoyIhIQ=='
DB<11> x uri_unescape("JiRkYWN%2ByoyIhIQ%3D%3D")
0 'JiRkYWN+yoyIhIQ=='
Here is what should be happening. All I'm showing are the steps. I'm using perl in a debugger. Step 54 encodes the string to base64. Step 55 shows how the base64 encoded string could be made into a uri escaped parameter. Steps 56 and 57 are what the client end should be doing to decode.
这是应该发生的事情。我所展示的只是步骤。我在调试器中使用 perl。步骤 54 将字符串编码为 base64。步骤 55 显示了如何将 base64 编码的字符串制成 uri 转义参数。步骤 56 和 57 是客户端应该执行的解码操作。
One possible work around is to ensure that your base64 "key" does not contain any plus signs!
一种可能的解决方法是确保您的 base64“密钥”不包含任何加号!
DB<53> $key="AB~"
DB<54> x encode_base64($key)
0 'QUJ+
'
DB<55> x uri_escape('QUJ+')
0 'QUJ%2B'
DB<56> x uri_unescape('QUJ%2B')
0 'QUJ+'
DB<57> $result=decode_base64('QUJ+')
DB<58> x $result
0 'AB~'
回答by rcoopman
What may be happening here is that the URLDecode is turning the %2b
into a +
, which is being interpreted as a space character in the URL. I was able to overcome a similar problem by first urldecoding the string, then using a replace function to replace spaces in the decoded string with +
characters, and then decrypting the "fixed" string.
这里可能发生的情况是 URLDecode 正在将%2b
转换为+
,它被解释为 URL 中的空格字符。我能够通过首先对字符串进行 urldecoding,然后使用替换函数用+
字符替换解码字符串中的空格,然后解密“固定”字符串来克服类似的问题。