如何避免在点击电子邮件中的链接时启动浏览器

9

目前,我的应用程序的一部分会向用户发送电子邮件提醒他们事件或任务。当在电子邮件客户端中点击MarkComplete链接时,将向我的ActionHandler.ashx(一个HTTP处理程序)发出HTTP Get请求,其中QueryString参数是输入,允许更新事件/任务。然后向客户端发出新的电子邮件,表示完成。这个工作正常。

这个HTTP GET到处理程序的不良副作用是启动浏览器(即此时打开浏览器是不需要的,也很烦人)。

假设:当我学习ASP.Net Web Api时,我认为我可以将HTTPHandler中的少量代码重构为Web API控制器中的PUT方法。我理解这个控制器可以在进行上述所述的必要处理之后响应void返回(HTTP状态码204)。

问题:在Web API控制器中新编写的上述方法是否可以返回204,并且是否会完全防止浏览器启动?我希望最终用户单击其第一个电子邮件中的链接,仅获得新构建的电子邮件消息,表示“完成”(这里根本没有浏览器)。

编辑以澄清于2016年5月22日:

  • 不需要“用户互动”。理想情况下,用户点击后对用户没有任何影响,只会收到一个新的“回复电子邮件”,表示任务成功完成。
  • 下面提出的第2个选项已经尝试过了,并且一些主要的电子邮件程序不允许这样做-请参见:Submit to HttpHandler results in RequestType GET instead of POST
  • 请注意,当前发出的HTML电子邮件内容不包含将链接标签括在消息中的任何HTML表单标签。
  • 那么,我真的没有任何选择吗?我已经阅读过HTTP PUT可以处理查询字符串(我不知道如何确切地做到...)
3个回答

5

简短回答:不行

如果您需要用户交互,则无法在未打开浏览器的情况下从电子邮件客户端执行HTTP请求。

大多数电子邮件客户端(包括网络邮件)不允许您执行JavaScript代码,因此您没有后台执行某些操作的选项。

这意味着您有两个选择:

  1. 在电子邮件中创建一个链接,该链接将导致向您的Web服务器发送GET请求(这是您已经完成的)。当然,这会导致浏览器打开该页面。
  2. 在电子邮件中创建一个HTML表单,其中包含一个隐藏字段,该字段包含您的数据,该表单将定位到Web服务器内启用了POST的端点。这也会导致Web浏览器被打开(在某些情况下可能还会显示警告消息),但可以更好地处理要发送的数据类型。 但是,似乎这种方法与特定客户端行为紧密绑定(例如Thunderbird将每个表单提交转换为GET请求),因此我不认为这是可行的。

除了这两个选项,我认为您没有其他选择。原因纯粹与安全有关:如果您能够在电子邮件消息中执行JavaScript代码,那么这将非常不安全。

204响应

你可以将终端的响应转换成 204(就像你提出的那样)。请注意,这也会导致你的浏览器打开,但几乎立即关闭响应 204 的选项卡(确切的行为取决于电子邮件客户端和 Web 浏览器组合)。
我认为即使您不更改代码库并继续使用 ActionHandler.ashx,这也可以轻松完成,但如果您想要,在 ASP.NET Web API 中仅通过从 ActionMethod 返回 void 即可 returning void
关于 PUT 方法:
在HTML表单中,只允许使用GETPOST方法。而任何类型的<a href="... ">...</a>标签始终会生成一个GET请求。这意味着您将无法在电子邮件消息中执行PUT方法(无论在哪个环境中读取电子邮件)。

感谢您周到的回复。请查看我在原帖底部的修改。 - John Adams
我看到了你的编辑,但即使如此,我的答案仍然没有改变(除了HTML表单选项似乎绑定到电子邮件客户端特定的行为)。当我说“用户交互”时,我指的就是你所问的:例如,用户点击某个东西。这就是一种交互。另外,我不知道你在哪里读到关于PUT方法的差异,因为查询字符串参数可以从任何请求(GETPOSTPUTDELETEWHATEVER)中读取,因为它们是URI的一部分。 - Federico Dipuma
关于上述查询字符串问题,显然我无法访问 Request.Querystring("SomeKeyword") 来解析值,需要使用 FromURI 属性来拆分查询字符串。如果我能学会如何做到这一点,我想我可以尝试将我的 HTTPhandler 代码移植到返回 HTTP 状态 204 的 Web 服务中。 - John Adams
也许你正在寻找 Request.GetQueryNameValuePairs(); - Federico Dipuma

1

在电子邮件中执行操作需要打开一个网页浏览器,否则这将成为客户端的一个严重安全隐患。如果这是一种选项,那么这将为垃圾邮件发送者和黑客打开一扇门,他们可以通过点击任何地方自动下载应用程序(非常危险)。

有其他方式来处理此类应用程序,我们使用短信以及可以回复应用程序请求的PDF表格,只要客户端是您的基础设施的一部分,SharePoint就可以做到这一点。Google现在正在使用标记语言为RSVP和突出显示电子邮件提供此服务,但仅适用于查看标记语言和谷歌应用程序的客户端。大多数电子邮件客户端将忽略电子邮件中的标记和脚本。我真的不知道现在还有谁没有手机,即使我75岁的祖母也有手机。我建议使用twilioSignalR。另一种方法是设置几个电子邮件帐户,让您的应用程序监视,比如accept@yourdomain.com和deniy@yourdomain.com。现在当客户端接受时,它会向该电子邮件发送响应,您的应用程序可以查看标题中的电子邮件地址来标记该帐户,这还可以为您提供记录,以便在客户端出现问题时回顾。至于浏览器打开,我认为这不是什么坏事,这将把他们送回到您的应用程序,并强制他们查看您发布的新信息、事件或任务(营销)。

感谢您的回复,Rich。如果电子邮件消息中的href URL指向处理Web服务器上数据的Web服务,并返回HTTP状态204,则为什么需要打开浏览器?应用程序的一个组件控制“通知”电子邮件。链接的目标将是一个Web服务(将进行处理但不需要显示)。最终用户将“放心”,确认电子邮件很快会到达电子邮件客户端的收件箱。您整个第一段听起来都很严重。在某种程度上,您暗示它确实可能存在,但具有安全风险。 - John Adams
另外,我简要地了解了SignalR,但我无法看出它如何响应电子邮件中的链接点击。也许您将其作为电子邮件的替代方案建议?这可能意味着我需要大量重写我的应用程序。 - John Adams
抱歉回复晚了。关于浏览器打开,是浏览器发送数据。如果没有浏览器,哪个程序会将您的数据发送回来呢?现在您可以通过 Telnet 完成此操作,但这意味着所有客户端都需要安装 Telnet 客户端。 - pool pro
另一个选择是创建一个适用于Windows和手机系统的应用程序来提醒客户。有很多方法,但由于您已经设置了代码,我只能建议设置电子邮件地址以接受客户的回复,并在您的应用程序中添加逻辑以读取电子邮件标题。正如所说,有很多正确的方法可以做到这一点,而不违反电子邮件法规。 - pool pro
话虽如此,我从不介意通过电子邮件被重定向到浏览器上的我的账户信息页面来接受或拒绝有关我的账户的信息。这样做可以使客户记录更加更新,因为他们很可能会在强制登录时更新其信息中的任何更改。如果他们从未登录过,则客户信息将变得陈旧。希望这能对您有所帮助。 - pool pro
看看MailSystem.NET,它具有出色的功能,并且应该很容易添加到您的项目中以在后台运行,从接受@yourdomain.com或reject@yourdomain.com帐户收到的电子邮件自动更新数据。http://mailsystem.codeplex.com/ - pool pro

0

首先,为了发送任何HTTP请求(无论您使用的是GET、POST、PUT、DELETE、HEAD等动词),您需要一个外部程序(浏览器、shell等)来完成这个任务,因为电子邮件客户端无法实现此功能。

如果您不想使用Web浏览器,可以考虑其他方法。例如,将第一封发给用户的电子邮件配置为具有特定主题,例如“约会确认”,并告诉用户按原样回复此电子邮件,这将向您发送一封电子邮件,其中包括您发送给用户的原始主题,然后您可以将应用程序配置为期望此类传入电子邮件,并通过发送第二封电子邮件来响应此事件。您甚至可以使用包含在第一封电子邮件中的用户信息来配置第二封电子邮件。


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