生成URL个字符时任意移动

When Generating URL Characters Being Arbitrarily Moved

从客户那里收到此邮件,我们的密码重置电子邮件通常会正确生成,但是(在代码中)看起来像这样:

 <h4> <a href="https://'.$this->server.'/password?email_token='.$email_token.'&user_email='.$user_email.'">reset here</a></h4>

生成的字符串如下:

https://password/?email_token=111111111111111111111aaaaaaabbbb&user_email=info@mail.com

最后,它应该是这样的:

    https://website.com/password?email_token=111111111111111111111aaaaaaabbbb&user_email=info@mail.com

这是有趣的部分:

.'/password?

生成如下:

password/?

不知何故,在生成电子邮件时,'password' 之前的“/”移到了密码之后,但在“?”之前

这是一个静态字符串片段,怎么会这样?

这是由 URL 客户端(Chrome、FireFox、Edge 以及可能的其他客户端解释器,如 outlook)中的解析引起的问题。我没有测试 Opera,但它不会出现在 Internet Explorer 11 中。

有关详细信息,请参阅:https://webkit.org/blog/7086/url-parsing-in-webkit/

URL 解析也可以由发送或接收 MTA 应用,例如; postfix、gmail、office.com 等。但是我对 postfix 和 gmail 的测试并没有改变电子邮件的源代码。
我们需要知道您的服务器配置和收件人的 MTA 才能进行验证。

PHP 源代码中的实际字符串输出和结果 HTML 符合预期

https:///password?email_token=111111111111111111111aaaaaaabbbb&user_email=info@mail.com

由于 $this->server 提供的域缺失,因此它不是有效的 URI,违规客户端解析 URL 并移动额外的 /

运行 下面的代码片段可以体验在浏览器中单击和鼠标悬停期间的 URL 解析:为简洁起见缩短了 URL 参数。

<a href="https:///password?email_token=1">Test</a>

渲染结果:


使用 new URL() 时,在 Javascript 中可能会遇到相同的行为。

var url = 'https:///password?e=1';
var u = new URL(url);
window.alert('Original: ' + url + "\nParsed: " + u.href);


然而,当提供域时,URL 不会改变。

<a href="https://example.com/password?email_token=1">Test</a>