这个问题,即如何向使用没有FileReader或FormData支持的浏览器的用户提供准确的反馈,一直困扰着我。我花了整整3天时间试图想出一个解决方案,最终只得到了接近于无解的东西。
让我们看看事实:
- 浏览器:IE8/9 // 几乎没有其他没有FileReader支持的浏览器
- 上传行为:由于用户体验原因,我们需要它是“Ajax”
- 工具箱:
jQuery File Upload*
那么,除了使用iframe上传文件之外,就没有其他上传文件的方法了。对吗?
所以,像@jeferry_to所描述的那样,使用jQuery Iframe Transport的jQuery文件上传工具就是这项工作的工具。
*实际上,这个工具/插件并没有改变任何东西...
现在怎么办?
好吧...我们需要在传输iframe内部访问S3响应。但是我们不能这样做,因为它在不同的域上。因此,我们决定使用涉及第二个iframe的技巧来处理它。
设置如下:
- TopFrame,我们的页面(www.myhost.com)
- iframe TransportFrame(s3.amazonaws.com),由插件自动生成 - 包含S3响应
- iframe XDMFrame(s3.amazonaws.com),在需要时访问TransportFrame,获取响应并将其传递给TopFrame
情景:
首先,我们需要修改jQuery Iframe Transport,以便它不会自动删除自动生成的表单和传输框架。我们需要这样做是因为后面将使用的#postMessage本质上是异步的,我们不希望在尝试访问它时iframe已经消失了。
- 在TopFrame中,我们使用jQuery文件上传将文件上传到S3。现在我们想要确保它已经被上传,并在出现错误时获得错误信息。
- TopFrame使用#postMessage向XDMFrame发送跨域消息,提供TransportFrame的名称。该消息实际上是说:“嘿,请检查iframe X的内容,并在你完成后将其发送回给我。”
- XDMFrame然后执行类似于
top.frames ['iframe X'] .document.documentElement
的操作,以访问TransportFrame的内容,对其进行字符串化并通过#postMessage将其发送回TopFrame。
- TopFrame接收消息,向用户显示适当的反馈,并删除表单和iframe,因为我们使用了jQuery Iframe Transport修改。
好了,现在应该一切正常,因为所有步骤都是按照规定进行的。
不过,你甚至不需要费心。
你看...如果你强制现代浏览器使用iframe传输而不是XHR2,则上述解决方案确实会像魔术般地工作。
然而,这毫无意义。我们希望它在IE8 + 9中工作。
嗯...在IE8/9中,它有时可以工作,有时不能。通常情况下,它不起作用。
因为IE友好的HTTP错误消息,所以为什么?没错,你读得很清楚。在出现错误时,S3会响应一个HTTP错误状态,具体取决于错误(400、403等)。现在,根据响应的状态和长度(如
here所示),IE会丢弃S3的响应并替换为友好的错误消息。为了克服这个问题,您必须确保响应始终大于512字节。在这种情况下,您无法保证任何东西,因为您无法控制响应。S3可以控制,而典型的错误少于512字节。
简而言之:
iframe技巧适用于那些不需要它的浏览器,而对于那些需要它的浏览器则不起作用。
不幸的是,我想不到其他任何办法,所以这个案例对我来说已经结束了。