通过jQuery.ajax使用FormData POST提交Blob

9
我看到很多人都问过这个问题,但是无论我怎么尝试,仍然没有结果:

如何将Blob附加到表单数据中并通过jquery进行POST?

var reader = FileReader(); 
reader.readAsBinaryString(f);
reader.onload = function() {
    var slice = reader.result.slice(0,100, {type: "application/octet-stream"});

    var formdata = new FormData();
    formdata.append("blobData", slice); // I have verified via console.log(slice) that this has data
    formdata.append("blobName", "Photo");

    send(formdata);
}

function send(data) {
    $.ajax({
        url: "/upload",
        type: "POST",
        data: data,    
        cache: false,
        contentType: false,
        processData: false
    });
}

所有非 Blob 类型的键/值都在请求中,即使是 Blob 的键...但没有 Blob 数据。
有趣的是,当我使用 Firefox 而不是 Chrome 发布时,我在上面得到了一点数据...但不多(这应该是最多 2 MB 的数据...它只有 7 字节)。
1个回答

5

我最近遇到了这个确切的问题,并找到了解决方法。

核心问题在于,由readAsBinaryString传递给reader.onloadreader.result的值是一个字符串,而不是Blob。听起来很明显,但我也假设我正在使用Blob。由于String和Blob对象都有一个slice方法,变量slice虽然设置了看起来像二进制数据的数据,但仍然只是一个字符串。String.slice()方法与Blob.slice()方法完全相同,只忽略第三个参数,这就是为什么您没有注意到实际发生的事情。

根据FormData规范,任何不是Blob或File对象的值都会被转换为字符串。似乎slice字符串在第一个非ASCII字符处被截断(我只是猜测确切的原因,但重要的是该字符串在附加到formdata时肯定被截断)。

解决方案是先将reader.result转换为Blob:

reader.onload = function() {
    var blob = new Blob([reader.result]), 
        slice = blob.slice(0,100, {type: "application/octet-stream"});

    var formdata = new FormData();
    formdata.append("blobData", slice);
    formdata.append("blobName", "Photo");

    send(formdata);
}

(该数组是 Blob 构造函数的要求。)
现在,由于 Blob.slice() 方法返回一个 Blob 对象,因此 slice 是一个 blob,并且可以附加到 formdata,而不会被字符串转换所破坏。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接