使用 Ajax XMLHttpRequest 上传文件

Posted

技术标签:

【中文标题】使用 Ajax XMLHttpRequest 上传文件【英文标题】:Upload file with Ajax XMLHttpRequest 【发布时间】:2011-09-06 20:34:07 【问题描述】:

我正在尝试使用此代码发送带有 XMLHttpRequest 的文件。

var url= "http://localhost:80/....";
$(document).ready(function()
    document.getElementById('upload').addEventListener('change', function(e) 
        var file = this.files[0];
        var xhr = new XMLHttpRequest();
        xhr.file = file; // not necessary if you create scopes like this
        xhr.addEventListener('progress', function(e) 
            var done = e.position || e.loaded, total = e.totalSize || e.total;
            console.log('xhr progress: ' + (Math.floor(done/total*1000)/10) + '%');
        , false);
        if ( xhr.upload ) 
            xhr.upload.onprogress = function(e) 
                var done = e.position || e.loaded, total = e.totalSize || e.total;
                console.log('xhr.upload progress: ' + done + ' / ' + total + ' = ' + (Math.floor(done/total*1000)/10) + '%');
            ;
        
        xhr.onreadystatechange = function(e) 
            if ( 4 == this.readyState ) 
                console.log(['xhr upload complete', e]);
            
        ;
        xhr.open('post', url, true);
        xhr.setRequestHeader("Content-Type","multipart/form-data");
        xhr.send(file);
    , false);
);

我收到此错误:T

请求被拒绝,因为没有找到多部分边界。

我做错了什么?

【问题讨论】:

【参考方案1】:
    没有xhr.file = file;这样的东西;文件对象不应该以这种方式附加。

    xhr.send(file) 不发送文件。您必须使用FormData 对象将文件包装成multipart/form-data 发布数据对象:

    var formData = new FormData();
    formData.append("thefile", file);
    xhr.send(formData);
    

之后,可以在$_FILES['thefile'] 中访问该文件(如果您使用的是 php)。

记住,MDC 和 Mozilla Hack demos 是你最好的朋友。

编辑:上面的(2)是不正确的。它确实发送了文件,但它会将其作为原始发布数据发送。这意味着您必须自己在服务器上解析它(这通常是不可能的,取决于服务器配置)。阅读如何在 PHP here 中获取原始帖子数据。

【讨论】:

xhr.send(file) 基于 XHR2,它是 XMLHttpRequest 对象的新版本,仅在某些浏览器中可用。 @nkassis 是的,但它会将文件本身作为帖子正文发送,而不是构造一个多部分的帖子数据供服务器解析。 此方法至少需要 IE10 或 android 3.0。 @gmustudent 是的,继续追加。 MDN 有一篇关于这个主题的优秀文章Using FormData Objects Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'

以上是关于使用 Ajax XMLHttpRequest 上传文件的主要内容,如果未能解决你的问题,请参考以下文章

15. 利用ajax jquery 上传文件

通过jQuery Ajax使用FormData对象上传文件

使用 XMLHttpRequest 上传文件

通过jQuery Ajax使用FormData对象上传文件

通过jQuery Ajax使用FormData对象上传文件

XmlHttpRequest2 进度事件和 ExtJS 3.3 Ext.Ajax