使用 Ajax XMLHttpRequest 上传文件

IT技术 javascript ajax jquery file-upload xmlhttprequest
2021-01-14 08:21:03

我正在尝试使用此代码发送带有 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个回答
  1. 没有这样的事情xhr.file = file;文件对象不应该以这种方式附加。
  2. xhr.send(file)不发送文件。您必须使用该FormData对象将文件包装到multipart/form-data发布数据对象中:

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

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

请记住,MDCMozilla Hack 演示是您最好的朋友。

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

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