Internet Explorer(默认设置,我通常认为它将在Great Unwashed的桌面上生效)似乎不喜欢在HTTP响应中接受附件内容的想法,如果相应的请求不是直接来自用户操作(像“点击”处理程序,或本机表单提交)。可能有更多的细节和细微差别,但这是让我感到沮丧的基本行为。
在我看来,这种情况很常见:一些可下载内容前面的用户界面 - 比如准备好的PDF报告 - 允许在创建内容时使用一些选项和输入。现在,与允许用户规定应用程序如何执行某些操作的所有表单一样,输入可能是错误的。不总是,但有时候。
因此存在两难问题。如果客户端尝试做一些奇特的事情,比如运行AJAX事务让服务器审查表单内容,然后重新提交以获取下载,IE就不会那样了。它不会喜欢它,因为带有附件的实际HTTP事务不会发生在原始的用户操作事件处理程序中,而是发生在AJAX完成回调中。更糟糕的是,由于IE安全栏似乎认为解决所有问题的方法是简单地从其原始URL重新加载外页,因此邀请用户继续下载可疑内容甚至都不起作用。
另一个选择是让表格消失。服务器检查参数,如果有任何错误,它将使用表单容器页面进行响应,并适当地填写错误消息。如果表单内容正常,它会生成内容并将其作为附件发送回HTTP响应中。在这种情况下(我认为),IE很高兴,因为内容显然是由用户直接请求的(顺便说一下,这是一种从坏内容中讲出好内容的荒谬脆弱的方式)。这很好,但现在的问题是客户端环境(即我的页面上的代码)无法判断下载是否有效,因此表单仍然只是坐在那里。如果我的表单处于某种对话框中,那么当操作完成时我真的需要关闭它 - 实际上,这是以AJAX方式执行它的动机之一。
在我看来,唯一要做的就是在表单对话框中添加一些消息,例如“下载开始时关闭它”。这对我来说真的很蹩脚,因为它是“请按下我的按钮”界面的一个例子:理想情况下,我自己的代码应该能够在适当的时候推动buutton。我不知道的一个关键问题是客户端代码是否有任何方法可以检测到表单提交导致附件下载。我从来没有听说过如何发现这一点,但这会打破我的僵局。
我认为你提交的表格有不同的目标窗口;因此形式保持不变。
有几种选择。
- 保持提交按钮被禁用并在后台进行持续验证,轮询表单以更改字段,然后在字段更改时触发对字段的验证请求。当表单处于有效状态时,启用该按钮;如果不是,请禁用该按钮。这并不完美,因为会有延迟,但对于你正在做的事情来说它可能已经足够了。
- 做基本验证,不需要在表单的处理程序中往返服务器
submit
事件,然后提交表单并将其删除(或可能只是隐藏它)。如果服务器上的进一步验证检测到问题,它可以返回一个使用JavaScript的页面来告诉原始窗口重新显示表单。
- 使用会话cookie和唯一的表单ID(当前时间来自
new Date().getTime()
会做);提交表单时,禁用其提交按钮,但保持可见,直到响应返回。使响应设置为具有指示成功/失败的ID的会话cookie。每隔一秒左右让窗口包含cookie的表单轮询,并在看到它时对结果进行操作。 (我从来没有做过最后一次;不是 立即 看看它为什么不起作用。)
我希望还有十几种其他的方法可以让这只猫受到影响,但是有三种可以想到它们。
(编辑) 如果你没有提交给不同的目标,你可能希望继续这样做 - 隐藏 iframe
在同一页上。 (可能与上述或其他答案相结合)可能有助于您获得所需的用户体验。
我认为你提交的表格有不同的目标窗口;因此形式保持不变。
有几种选择。
- 保持提交按钮被禁用并在后台进行持续验证,轮询表单以更改字段,然后在字段更改时触发对字段的验证请求。当表单处于有效状态时,启用该按钮;如果不是,请禁用该按钮。这并不完美,因为会有延迟,但对于你正在做的事情来说它可能已经足够了。
- 做基本验证,不需要在表单的处理程序中往返服务器
submit
事件,然后提交表单并将其删除(或可能只是隐藏它)。如果服务器上的进一步验证检测到问题,它可以返回一个使用JavaScript的页面来告诉原始窗口重新显示表单。
- 使用会话cookie和唯一的表单ID(当前时间来自
new Date().getTime()
会做);提交表单时,禁用其提交按钮,但保持可见,直到响应返回。使响应设置为具有指示成功/失败的ID的会话cookie。每隔一秒左右让窗口包含cookie的表单轮询,并在看到它时对结果进行操作。 (我从来没有做过最后一次;不是 立即 看看它为什么不起作用。)
我希望还有十几种其他的方法可以让这只猫受到影响,但是有三种可以想到它们。
(编辑) 如果你没有提交给不同的目标,你可能希望继续这样做 - 隐藏 iframe
在同一页上。 (可能与上述或其他答案相结合)可能有助于您获得所需的用户体验。
有很多 真的很好的理由 IE做到了这一点,我确信这不是任何人都会争论的 - 所以主要目标是以某种方式绕过它以使用户更好。
有时它值得重新思考事情是如何完成的。也许禁用按钮,使用javascript检查所有字段何时填写,并在ajax请求发出后触发。如果ajax成功,请启用该按钮。这只是一个建议,我相信会有更多......
编辑:更多...
做简单的提交(非AJAX),如果检查失败,发送一个 页 回来而不是附件。发回的页面可能包含最初提交的所有信息(加上向用户提供的任何错误消息),因此用户无需再次填写整个表单。而且我也相信会有更多的想法......
编辑:更多...
我相信你以前见过这种类型的东西 - 是的,它 是 一个额外的点击(不理想,但不是很难)....“如果您的下载失败,请单击此处” - >在这种情况下,按照您想要的方式执行此操作,但是向页面添加新的链接/按钮当AJAX返回时,如果下载失败,他们可以从“直接用户操作”提交已经验证的表单。我相信我会想到更多(或其他人会).....
我一直在打一个类似的问题。在我的情况下,如果我的网络应用嵌入在另一个网站上的iframe(第三方cookie问题),则发布到隐藏的iframe不起作用,除非我们的网站已添加到“可信站点”列表中。
我发现我可以将下载分解为POST和GET序列。该帖子返回一个短暂的GUID,可以在GET请求中用于启动下载。 POST可以执行表单验证,也可以在成功响应中返回GUID。客户端具有GUID后,您可以将隐藏的iframe元素的src属性设置为下载URL。浏览器看到'Content-Disposition':'attachement'标题,并为用户提供下载文件的下载功能区。
到目前为止它似乎适用于所有最新的浏览器。不幸的是,它要求您修改服务器端API以下载文件。