2010-01-14 33 views
11

Internet Explorer(默认设置,我通常假定它将在Great Unwashed的桌面上生效)似乎不喜欢在HTTP响应中接受附件内容的想法,如果相应请求不是直接从用户创建的操作(如“点击”处理程序或本地表单提交)。可能有更多的细节和细节,但这是令我感到沮丧的基本行为。什么是解决IE文件下载安全规则的技术?

在我看来,这种情况很普遍:某些可下载内容前的用户界面说,准备好的PDF报告—允许在创建内容时使用某些选项和输入。现在,与允许用户规定应用程序如何执行某些操作的所有形式一样,输入可能是错误的。并不总是,但有时候。

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

另一种选择是只让表格开火。服务器检查参数,如果有任何错误,它会用表单容器页面作出响应,并用错误消息进行适当的插入。如果表单内容正常,它会生成内容并将其作为附件发回HTTP响应。在这种情况下(我认为),IE很高兴,因为内容显然是用户直接请求的(顺便说一句,这是一种可笑的方式来告诉坏内容中的好内容)。这很好,但现在的问题是客户端环境(也就是我的页面上的代码)无法确定下载是否正常工作,因此表单仍然只是坐在那里。如果我的表单处于某种对话框中,那么当真正完成操作时,我真的需要关闭该表单,这是实现AJAX方式的动机之一。

在我看来,唯一需要做的就是在窗体对话框中添加一些类似于“下载开始时关闭它”的消息。这对我来说真的很蹩脚,因为它是“请为我按下这个按钮”界面的一个例子:理想情况下,我自己的代码应该能够在合适的时候推动这个按钮。我不知道的一个关键是,是否有任何方式让客户端代码检测到表单提交导致附件下载。我从来没有听说过检测这种方法,但这会打破我的僵局。

回答

8

我认为你要提交与不同的目标窗口的形式;因此形式留在原地。

有几种选择。

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

我预计大约有十多种方法对皮肤这只猫,但那些有三个是来到心神。

(编辑)如果您没有提交不同的目标,则可能需要继续并执行此操作 - 在同一页面上隐藏iframe。这(可能与以上或其他答案结合)可能会帮助您获得所需的用户体验。

+0

不,当您提交表单并且响应是附件(即要下载的文件)时,浏览器不会重新绘制页面。 – Pointy 2010-01-14 15:04:13

+0

最后一个看起来真是个好主意!如果下载失败,我不知道cookie是否会成功设置。明智的想法,无论它的工作与否! – Graza 2010-01-14 15:05:48

+0

@Pointy:啊,好吧,它确实有点奇怪。我认为这些基本的想法可以适应你正在做的事情,但不会深陷其中...... @格拉扎:那很好。如果它不起作用,我不认为我称它为“精彩”,但是谢谢。 :-) – 2010-01-14 15:10:03

2

有很多真的很好的理由 IE做到了这一点,我敢肯定这不是任何人会争辩的 - 所以主要目标是绕过它以某种方式让你的用户变得更好。

有时它值得重新考虑事情是如何完成的。也许禁用按钮,使用JavaScript来检查所有字段被填写的时间,并且一旦它们发出就会触发ajax请求。如果ajax成功,启用该按钮。这只是一个建议,我相信会有更多...

编辑:更多...

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

编辑:更多...

我敢肯定,你以前见过这种类型的东西 - 是的,这是一个额外的点击(不理想,但不硬)....一个“如果你的下载失败,请点击这里” - >在这种情况下,按照你想做的那样做,但是当AJAX返回时在页面上添加一个新的链接/按钮,所以如果下载失败,他们可以提交已经通过“直接用户行为”验证了表单。我相信我会想到更多(或其他人会).....

+0

嗯,我同意IE为了“良好”的原因这样做,但很大程度上,这些原因涉及其他系统软件不太聪明。请注意,Firefox和Safari和Chrome没有这个问题,据我所知,这并不是一个重要的安全漏洞。 – Pointy 2010-01-14 15:06:05

1

我一直在争取一段时间的类似问题。在我的情况下,如果我的网络应用嵌入在另一个网站的iframe中(第三方cookie问题),则发布到隐藏的iframe不起作用,除非我们的网站已添加到“可信站点”列表中。

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

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

+0

这很好,但严重的“cookie技巧”是一种安全可靠的方式,使交互工作。 – Pointy 2017-12-11 21:39:25

+0

@Pointy我真的很喜欢cookie技巧,我相信它会为你工作。我试过了,但正如我所说的,当Web应用程序在由第三方托管的iframe中运行时,我需要下载才能在IE11中工作。 Cookie部分可以工作,但是如果我尝试将表单发布到隐藏的iframe,IE将会使用下载功能区。 - 我只是添加了我的答案,以防有人发现它有用。 – 2017-12-11 22:54:14

+0

是的,这可能会造成很大的差异。我的网站很漂亮。 – Pointy 2017-12-11 22:56:25