是否可以通过$ .ajax(options)或xhr.send(file)上传文件?

时间:2011-05-24 08:43:54

标签: javascript jquery ajax html5 file-upload

我正在使用文件api和xhr2规范。我使用FormData$.ajax(options)创建了一个上传器(由旧浏览器支持flash),其中带有File的FormData对象是options.data对象的一部分。一切正常。

现在我决定删除FormData,因为浏览器支持较弱。除了

,我无法找到上传文件的方法
var xhr = new XMLHttpRequest();
xhr.setRequestHeader("Cache-Control", "no-cache");
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.setRequestHeader("X-File-Name", file.name);
xhr.send(file);

哪些不会返回我可以在递归函数中使用的Promise。

我的代码是这样的:

   startUpload: function() {
        var that = this;
        that.recurseSend(that.queue);       
    },

    _initProgressListener: function (options, file) {
        var that = this;
        var xhr = $.ajaxSettings.xhr();
        options.contentType = 'multipart/form-data';        
        options.processData = false;
        options.type = 'POST';
        // WHAT TO DO HERE TO avoid FormData???? What ever I put into options.data - fails

        /* THIS WOULD WORK
        var formData = new FormData();
        formData.append('file', file);
        options.data = formData;
        */            

        if (xhr.upload && xhr.upload.addEventListener) {
            xhr.upload.addEventListener('progress', function (e) {
                that._onProgress(e, file);
            }, false);
            options.xhr = function () {
                return xhr;
            };
        }
    }, 

    recurseSend: function (queue) { 
        var file = queue.pop();
        if(file != undefined) {
            var that = this;
            var options = that.options;    
            that._initProgressListener(options, file);

            var send = function() {
                jqXHR = ($.ajax(options)).done(function(result, textStatus, jqXHR) {
                        that._onDone(result, textStatus, jqXHR, file);
                        queue.stats['successful_uploads']++;
                    }).fail(function(jqXHR, textStatus, errorThrown) {
                        that._onFail(jqXHR, textStatus, errorThrown, file);
                        queue.stats['upload_errors']++;
                    }).always(function(result, textStatus, jqXHR) {
                        that._onAlways(result, textStatus, jqXHR, file);
                        queue.stats['files_queued']--;
                        that.recurseSend(queue);
                    });
                    return jqXHR;
            };

            this._beforeSend(file);              
            return send();
        }
    },

要简短,$.ajax(options)如果xhr.send(formData)解析为options.data = FormData,但如何将其解析为xhr.send(file)

编辑:我正在玩它,如果我设置options.data = file;然后$ .ajax(options)执行xhr.send(theFile);但错误Error: INVALID_STATE_ERR: DOM Exception 11

并且请求作为POST multipart / form-data请求发送,但没有包含文件的multipart body

如果我将它放入options.data = {file: file};,无论processData属性是否设置为true,它都会被序列化。

4 个答案:

答案 0 :(得分:2)

您可以使用FileReader或类似API从HTML5文件数据中手动生成上传的MIME数据。退房:https://github.com/coolaj86/html5-formdata。虽然这取决于getAsBinary(),但这会更多或更少 - 将其更改为也能够使用FileReaderreadAsBinaryString()可能会更加跨浏览器兼容。

请注意,这在IE7 / 8中仍然无法正常工作,正如其他人所说的那样,如果不诉诸Flash或iframe,就无法做到这一点。话虽这么说,如果你使用File,大概你也不关心IE7或IE8 ......

答案 1 :(得分:0)

每当您处理从用户计算机上传任意数据时,答案通常是“不,如果可以,那就是错误”。

这让我觉得有些违反安全规定的行为。您无法更改文件输入控件的值或执行许多其他操作,包括读取文件的真实路径或其内容。此外,在某些平台上,你甚至没有文件大小(IE,我在看你),没有弹出一些安全对话框(通过activex控件)。鉴于所有这些问题,我可能会说,即使您确实找到了解决方案,它也可能被视为未来的错误并被删除或更改。

换句话说,除非您找到明确支持它的信誉良好的来源,否则我认为这不是一件安全的事情......就像chrome dev博客一样。

答案 2 :(得分:0)

我自己使用了valums ajax uploader。你可以从这里得到它: http://valums.com/ajax-upload/。它工作得非常好。我不知道确切的实现细节,但这里有一个非常简短的描述:

“此插件使用XHR上传多个文件,其中包含FF3.6 +,Safari4 +,Chrome中的进度条,并在其他浏览器中回退到隐藏的基于iframe的上传,从而在各处提供良好的用户体验。”

所以听起来它非常接近你想要的东西。这是从服务器的角度(从server / readme.txt)描述它的工作方式的另一部分信息:

  1. 对于IE6-8,Opera,其他浏览器的旧版本,您获取该文件 您通常使用常规的表单上传。

  2. 对于使用进度条上传文件的浏览器,您需要获取原始文件 发布数据并将其写入文件。

  3. 因此需要在服务器端进行特殊处理。幸运的是,它带有几个参考服务器端实现(perl,php和java),所以不应该太麻烦。快乐的ajax上传:)

答案 3 :(得分:-1)

How can I upload files asynchronously?

如果不通过iFrame,似乎无法做到这一点。在我链接的答案中似乎有工作片段,以及为你做的几个插件。

* 编辑,因为我收到了评论 *

是的,有可能 - http://caniuse.com/xhr2 - 虽然没有低于10的IE支持..

下载教程:

http://www.html5rocks.com/en/tutorials/file/xhr2/

http://www.profilepicture.co.uk/ajax-file-upload-xmlhttprequest-level-2/