有哪些技巧可以绕过 IE 文件下载安全规则?

IT技术 javascript jquery internet-explorer
2021-02-04 12:00:35

Internet Explorer(具有默认设置,我通常认为它会在 Great Unwashed 的桌面上生效)似乎不喜欢在 HTTP 响应中接受附件内容的想法,如果相应的请求不是直接从用户操作发出的(如“点击”处理程序,或本机表单提交)。可能还有更多细节和细微差别,但这是令我沮丧的基本行为。

在我看来,这种情况很常见:一些可下载内容(例如,准备好的 PDF 报告)前面的用户界面允许在创建内容时使用一些选项和输入。现在,与所有允许用户规定应用程序如何做某事的表单一样,输入可能是错误的。不总是,但有时。

因此有一个两难选择。如果客户端试图做一些花哨的事情,比如运行一个 AJAX 事务让服务器审查表单内容,然后重新提交以获取下载,IE 不会喜欢那样的。它不会喜欢它,因为携带附件的实际 HTTP 事务不会发生在原始用户操作事件处理程序中,而是发生在 AJAX 完成回调中。更糟糕的是,由于 IE 安全栏似乎认为解决所有问题的方法是简单地从其原始 URL 重新加载外部页面,因此它对用户继续下载可疑内容的邀请甚至不起作用。

另一种选择是让表格开火。服务器检查参数,如果有任何错误,它会响应表单容器页面,并适当地添加错误消息。如果表单内容正常,它会生成内容并将其作为附加文件在 HTTP 响应中发回。在这种情况下(我认为),IE 很高兴,因为内容显然是由用户直接请求的(顺便说一下,这是一种区分好内容和坏内容的可笑的站不住脚的方式)。这很好,但现在的问题是客户端环境(即我页面上的代码)无法判断下载是否有效,因此表单仍然只是坐在那里。如果我的表单在某种对话框中,那么我真的需要在操作完成时关闭它——真的,那个'

在我看来,唯一要做的就是为表单对话框配备消息,例如“下载开始时关闭它”。这对我来说似乎很蹩脚,因为它是“请为我按下这个按钮”界面的一个例子:理想情况下,我自己的代码应该能够在适当的时候按下按钮。我不知道的一个关键问题是客户端代码是否有任何方法可以检测到表单提交导致附件下载。我从来没有听说过检测这种情况的方法,但这对我来说会打破僵局。

3个回答

我认为您正在使用不同的目标窗口提交表单;因此形式停留在原地。

有几种选择。

  1. 保持提交按钮禁用并在后台进行持续验证,轮询表单以获取字段更改,然后在字段更改时触发验证请求。当表单处于有效状态时,启用按钮;如果不是,请禁用该按钮。这并不完美,因为往往会有延迟,但对于您正在做的任何事情来说,它可能已经足够了。
  2. 在表单submit事件的处理程序中执行不需要往返服务器的基本验证,然后提交表单并删除它(或者可能只是隐藏它)。如果服务器上的进一步验证检测到问题,它可以返回一个页面,该页面使用 JavaScript 告诉原始窗口重新显示表单。
  3. 使用会话 cookie 和唯一的表单 ID(从当前时间开始new Date().getTime());提交表单后,禁用其提交按钮但保持其可见,直到响应返回。使响应设置一个会话 cookie,该 cookie 具有指示成功/失败的 ID。让包含 cookie 表单的窗口每隔一秒左右轮询一次,并在看到结果时采取行动。(我从来没有做过最后一个;没有立即明白为什么它不起作用。)

我预计还有十多种其他方法可以给这只猫剥皮,但我想到了这三种。

(编辑)如果您没有提交给不同的目标,您可能想要继续这样做 -iframe同一页面上的隐藏这(可能与上述或其他答案结合)可能会帮助您获得所需的用户体验。

最后一个看起来真是个好主意!我想知道如果下载失败,cookie 是否会成功设置。好主意,不管它是否有效!
2021-03-26 12:00:35
饼干的想法真的很棒,现在我已经让它渗透到我头上停滞不前的脂肪层。该技术应称为 Crowder Cookie Trick。
2021-03-27 12:00:35
不,当您提交表单并且响应是附件(即要下载的文件)时,浏览器不会重新绘制页面。
2021-04-04 12:00:35
@Pointy:啊,好吧,看起来确实有点奇怪。我认为这些基本想法可以适应你正在做的事情,但不会深入了解它的本质...... @Graza:那太好了。如果它不起作用,我认为我不会称其为“出色”,但谢谢。:-)
2021-04-05 12:00:35
@Grae:我想出了这个答案——然后立即转身并在一个项目中使用它。很好用。就我而言,当用户从服务器请求自定义 PDF 时,我使用此技术显示“正在构建...”模式对话框 (div)。表单提交到隐藏的 iframe,然后我的代码轮询 cookie。一切顺利,响应返回Content-Disposition: attachment,弹出下载框;我的代码看到了 cookie 并关闭了模态。如果出现错误,我的代码会在 cookie 中看到错误并将其显示给用户。我真的必须用演示来写这个博客。:-)
2021-04-14 12:00:35

IE 这样做有很多很好的理由,我相信这不会引起任何人的争论——所以主要目标是以某种方式绕过它,为您的用户提供更好的服务。

有时值得重新思考事情是如何完成的。也许禁用按钮,使用javascript检查所有字段何时填写,并在填写完成后触发ajax请求。如果ajax成功,启用按钮。这只是一个建议,我相信还会有更多……

编辑:更多...

做简单的提交(非 AJAX),如果检查失败,发送一个页面而不是附件。发回的页面可能包含最初提交的所有信息(以及给用户的任何错误消息),因此用户无需再次填写整个表单。而且我也相信会有更多的想法......

编辑:更多...

我相信你以前见过这种类型的东西 - 是的,这一次额外的点击(不理想,但并不难)......“如果你的下载失败,点击这里” -> 在这种情况下,随心所欲,但在 AJAX 返回时向页面添加一个新链接/按钮,因此如果下载失败,他们可以通过“直接用户操作”提交已验证的表单。而且我敢肯定我会想到更多(或者其他人会).....

好吧,我同意 IE 这样做是出于“好的”原因,但在很大程度上,这些原因涉及其他系统软件不是很聪明。请注意,Firefox 和 Safari 以及 Chrome 没有这个问题,据我所知,这不被视为重大的安全隐患。
2021-04-13 12:00:35

我一直在与类似的问题作斗争。就我而言,如果我的 Web 应用程序嵌入到另一个站点的 iframe 中(第三方 cookie 问题),则发布到隐藏的 iframe 不起作用,除非我们的站点已添加到“受信任的站点”列表中。

我发现我可以将下载分解为 POST 和 GET 序列。该帖子返回一个短暂的 GUID,可用于 GET 请求以启动下载。POST 可以进行表单验证并在成功响应中返回 GUID。客户端获得 GUID 后,您可以将隐藏的 iframe 元素的 src 属性设置为下载 URL。浏览器会看到 'Content-Disposition': 'attachment' 标题,并为用户提供下载功能区以下载文件。

到目前为止,它似乎适用于所有最新的浏览器。不幸的是,它需要您修改服务器端 API 以下载文件。

@Pointy 我真的很喜欢 cookie 把戏,我相信它对你很有用。我试过了,但就像我说的,当 Web 应用程序在第三方托管的 iframe 中运行时,我需要下载才能在 IE11 中工作。cookie 部分有效,但如果我尝试将表单发布到隐藏的 iframe,IE 会吃掉下载功能区。- 我只是添加了我的答案,以防有人觉得它有用。
2021-03-16 12:00:35
是的,这可能会产生很大的不同。我的网站很普通。
2021-03-23 12:00:35
这很好用,但严肃地说,“cookie 技巧”是使交互工作的一种安全可靠的方式。
2021-04-12 12:00:35