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

lis*_*sak 12 javascript ajax jquery html5 file-upload

我正在使用文件api和xhr2规范.我创建了使用的上传(通过闪存旧版本浏览器的支持)FormData,并$.ajax(options)在那里与FORMDATA对象File是一部分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);
Run Code Online (Sandbox Code Playgroud)

哪个不返回我可以在递归函数中使用的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();
        }
    },
Run Code Online (Sandbox Code Playgroud)

为了缩短它,$.ajax(options)解析为xhr.send(formData)if,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属性是否设置为真.

Gij*_*ijs 2

您可以使用或类似的 API 从读取的 HTML5 文件数据中手动生成用于上传的 MIME 数据FileReader。查看: https: //github.com/coolaj86/html5-formdata。这或多或少会做到这一点,尽管这取决于getAsBinary()——将其更改为也能够使用FileReader,并且readAsBinaryString()可能会更加跨浏览器兼容。

请注意,这在 IE7/8 中仍然根本不起作用,并且正如其他人所说,如果不借助 Flash 或 iframe 就无法做到这一点。话虽这么说,如果您使用 File,想必您并不关心 IE7 或 IE8...