PHP URL编码问题

5

我使用rawurlencode()对令牌进行编码,发送HTML电子邮件以激活用户。

因此,电子邮件中的链接看起来像这样:

<a href="http://site.com/auth?action=confirmActivation&amp;user=79&amp;token=zlKoFo%22f%27g%3FtUb%27%29Z~L1%25zKh%5EG%23_Aj%5Ckbbbd4fdb9121b50f643f12c937ab1c03d5f09861" target="_blank">Click here to activate your account</a>

当我点击这个链接时,我的页面URL看起来像这样:
http://site.com/auth?action=confirmActivation&user=79&token=zlKoFo%22f%27g%3FtUb%27%29Z~L1%25zKh^G%23_Aj%5Ckbbbd4fdb9121b50f643f12c937ab1c03d5f09861

所以 - 在此之前的令牌(这是我的电子邮件中的样子):

zlKoFo%22f%27g%3FtUb%27%29Z~L1%25zKh%5EG%23_Aj%5Ckbbbd4fdb9121b50f643f12c937ab1c03d5f09861

之后的令牌:

zlKoFo%22f%27g%3FtUb%27%29Z~L1%25zKh^G%23_Aj%5Ckbbbd4fdb9121b50f643f12c937ab1c03d5f09861

看起来当我点击时,浏览器会自动进行一些转换?为什么呢?

1个回答

3
这是因为PHP对%5E (^)进行了url编码(它会对所有非字母数字字符进行编码,除了-和_)。这不符合RFC标准。浏览器看到这个问题后,会“修复”编码以符合RFC标准,即先解码所有内容,然后只编码在URL中引起问题的字符(^并不是其中之一)。PHP的rawurlencode是符合RFC标准的,但实际上,浏览器本身可能不符合RFC标准,只会像空格和~等一些字符进行编码。建议您只需对获取的令牌进行url解码并使用该结果,这样无论哪种情况都会保持一致。如果令牌中有问题字符,请对其进行base64编码来解决问题。

我发送的令牌符合RFC 3986标准。当我点击它时,浏览器会使其“不符合标准”。 - Stann
我认为我已经明白了:我的令牌虽然符合RFC 3986(url)标准,但包含HTML特殊字符:%22是“。这样,如果我发送纯文本电子邮件而不是HTML电子邮件,一切都将正常工作。 - Stann
浏览器在 href 标签内遇到 HTML 特殊字符时,会正确地将它们转换为实际字符。 - Stann
我猜如果我使用HTML电子邮件 - 我必须为我的令牌使用base64(URL版本)。该死。 - Stann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接