邮件客户端剥离部分 angular url

mail clients stripping part of angular url

我正在发送一封注册激活电子邮件,其中包含注册确认 url 以及指向 angular 前端应用程序的确认令牌:

... <a href="https://domain.com/#/confirm-signup?token=1234...">Activate</a> ...

请注意,令牌是一个 JWT,并且相当长。

这对大多数用户来说是有效的,但对于一些点击 link 的人来说,他们只是在没有 confirm-signup?token=...

的情况下将他们带到 https://domain/com

似乎邮件客户端可能会在 # 之后剥离所有内容,但我找不到任何其他人有此问题的证据,也无法重现。

到目前为止我最好的猜测是一些邮件客户端看到 # 并以某种方式将尾部部分视为内部锚点并将其剥离......?

有没有其他人遇到过这种问题?如果是这样,除了用其他东西替换整个机制之外,您是否找到任何解决方案?

是的,我之前遇到过这个问题,因为 #,我试图 link 到着陆页上的锚点。我的解决方案最终使用 short.url 服务 "hide" 来自 html 的 #,例如https://goo.gl/

看来你需要 percent encoding!

很多时候当你的 href 被解析时(在这种情况下被 angular 解析)它没有正确处理特殊字符,或者去除它们。找到您的问题字符并将它们替换为 %3F for ?,%26 for &,以及 %23 for #。其余的都在link.

的图表中

一旦编码地址到达浏览器,url 将在您的 url 栏中解码。

一些客户对待哈希-link 很好。其他人没有。这里有一段关于 Outlook 的讨论:Outlook strips URL hash from email

我们公司为解决此问题所做的只是在我们的服务器上创建一个重定向处理程序。您的电子邮件 link 将变为 http://domain.com/email-link?url=https%3A%2F%2Fdomain.com%2F%23%2Fconfirm-signup%3Ftoken%3D1234 并且您的服务器端脚本将获取查询参数 url 并立即触发重定向。

您需要确保找到电子邮件中的所有 link 并替换它们。这是一个 PHP 函数,但您可以使用您使用的任何后端语言来执行此操作。此处的正则表达式至少可能有所帮助。

function replaceLinks($html,$hash) {
    return preg_replace_callback('/<a [^>]*href=[\"\']{1}(.+?)[\"\\']{1}/', function($matches) use ($hash) {
        return str_replace($matches[1],"http://domain.com/email-link?url=".rawurlencode($matches[1]),$matches[0]);
  }, $html);
}