Javascript AmazonS3通过Iframes上传

Javascript AmazonS3通过Iframes上传,javascript,iframe,upload,amazon-s3,Javascript,Iframe,Upload,Amazon S3,唉,我们又回到这里了。我可以很容易地在任何像样的浏览器上使用CORS,直接将文件上传到我的AWS S3存储桶中。但是(它来了),我不得不回到Iframes。简单,设置一个隐藏的Iframe,创建一个表单,将其目标设置为Iframe name/id,提交表单。如果上传成功,Iframe将重定向到我指定的url,我可以访问我需要的任何内容。但是如果发生错误,因为Iframe现在位于AWS域上,我将无法访问错误的XML内容。事实上,我甚至不知道发生了错误 我曾在互联网上看到一些勇敢的人谈论过在将要上传

唉,我们又回到这里了。我可以很容易地在任何像样的浏览器上使用CORS,直接将文件上传到我的AWS S3存储桶中。但是(它来了),我不得不回到Iframes。简单,设置一个隐藏的Iframe,创建一个表单,将其目标设置为Iframe name/id,提交表单。如果上传成功,Iframe将重定向到我指定的url,我可以访问我需要的任何内容。但是如果发生错误,因为Iframe现在位于AWS域上,我将无法访问错误的XML内容。事实上,我甚至不知道发生了错误

我曾在互联网上看到一些勇敢的人谈论过在将要上传文件的同一个存储桶中托管一个html文件,然后使用postMessages路由Iframe内容,或者类似的东西

有人能给我解释一下如何实现这个神秘的解决方案吗?Blueimp的jQuery文件上传器似乎解决了这个问题,但天哪,代码太jQuery化了,我还没能理解它的要点

为清晰起见而编辑
  • IE在评论中总结我的答案:IE有CORS支持,但有一些限制:

    这种直接上传到S3的实现看起来比jquery fileupload简单得多,而且它不在jquery中:


    希望这有帮助

    关于jQuery文件上传插件如何进行iframe上传,您需要了解的几乎所有内容都在其(以及支持页面)中

    作为介绍,您可能希望阅读其wiki页面上的用户说明,特别是跨站点iframe传输上载部分。(注意,根据他们的页面,IE不支持上传进度之类的细节。至于“postMessage”场景,可能iframe应该包含一个简单的javascript

    [编辑]用于由错误消息接管的iFrame

    IFRAME脚本

    现在,parent非常了解iFrame,并且可以跟踪它的状态(取决于它是否回答简单的postMessage)

    父脚本


    如果iframe没有响应其“代码”iFrameTakenOver将永久设置为假检查,以验证是否发生了错误。

    使用不支持FileReader或FormData的浏览器向用户提供准确反馈的问题也困扰着我。我花了整整3天的时间试图想出一个解决方案,最后终于想出了一个解决方案一事无成

    让我们深入了解事实:

    • 浏览器IE8/9//成为不支持文件读取器的任何其他浏览器的可能性很小
    • 上传行为:出于用户体验的原因,我们需要它是“Ajax”
    • 工具带:*
    好的,那么除了使用iframe,没有其他上传文件的方法了,对吗

    因此,使用jQuery Iframe Transport作为@jeferry_上传jQuery文件是这项工作的工具

    *实际上,这个工具/插件并没有改变任何事情

    现在怎么办

    嗯…我们需要访问传输iframe中的S3响应。但是我们不能,因为它位于不同的域上。 所以我们决定使用这个技巧来处理它,这个技巧涉及到第二个iframe

    设置:

    • TopFrame,我们的页面(www.myhost.com)
    • iframe TransportFrame(s3.amazonaws.com),由插件自动创建,包含s3响应
    • iframe XDMFrame(s3.amazonaws.com),在订购时访问TransportFrame,获取响应并将其传递给TopFrame
    场景:

    首先,我们需要修改jQuery Iframe传输,这样它就不会自动删除自动生成的表单和传输框架。我们需要这样做,因为稍后使用的postMessage本质上是异步的,我们不希望Iframe在尝试访问它时消失

  • 在TopFrame上,我们使用jQuery file upload将一个文件上载到S3。我们现在要确保它已上载,否则会出现错误
  • TopFrame使用#postMessage向XDMFrame发送一条跨域消息,提供TransportFrame的名称。该消息实际上说:“嘿,检查iframe X的内容”,当您将它们发送回我时
  • XDMFrame然后执行类似于
    top.frames['iframe X'].document.documentElement
    的操作来访问TransportFrame的te内容,将其字符串化并通过#postMessage将其发送回TopFrame
  • TopFrame接收消息,向用户显示适当的反馈,并删除由于jQuery iframe传输修改而留下的表单和iframe
  • 好的,现在一切都应该开始了,因为一切都是按规定进行的

    不,你甚至不应该麻烦

    你看……如果你强迫一个现代浏览器使用iframe传输而不是XHR2,那么上面的解决方案确实会非常有效

    然而,这是毫无意义的。我们希望它在IE8+9中工作

    嗯……在IE8/9中,它有时工作,有时不工作。通常不会

    为什么?因为IE友好的HTTP错误消息。哦,是的,你读得很好

    如果出现错误,S3根据错误(400403等)以HTTP错误状态响应。现在,根据所示响应的状态和长度,IE将丢弃S3响应,并将其替换为友好的错误消息。为了克服这一问题,您必须确保响应始终大于512字节。在这种情况下,您无法保证任何类似的情况,因为您无法控制响应。S3会,典型的错误是OR小于512字节

    简而言之:

    iframe技巧适用于那些不需要它的浏览器,也不适用于那些需要它的浏览器


    不幸的是,我想不出其他任何东西,所以现在我的案子就结束了。

    为什么CORS不适用于IE?我用jquery fileupload插件得到了一个,但我还没有在IE上测试过。这篇文章似乎表明
    window.document.onload = function(e){ 
        window.parent.postMessage(document, '*'); //replace '*' with your parent if possible   
    }
    // just to get the proper document for the parent to target me
    window.addEventListener('message',function(e) {
        if (e.domain == 'example.com') { // the domain of your parent frame
            if (e.data == "Salute") {
                window.parent.postMessage("I'm here", '*'); //replace '*' with your parent too
            }
        }
    });
    
    var iFrameTarget;
    var iFrameTakenOver = false;
    var timer;
    window.addEventListener('message',function(e) {
        if (e.domain == 'example.com') { // the domain of your iframe
            if (e.data) { // e.data contains the iframe document
                if(typeof(e.data) =='object')
                    iFrameTarget = e.source;
                elseif(e.data == "I'm here")
                {
                    iFrameTakenOver = false;
                }
                timer =setInterval(call_iFrame(),5000); // check iFrame presence in 5 seconds
            }
        }
    });
    
    function call_iFrame() {
        iFrameTarget.postMessage('Salute');
        iFrameTakenOver = true;
    }