8

我已经多次看到这个问题被问到,但是尽管我尝试了很多,但我仍然没有看到任何结果:

如何附加 Blob 以形成数据并通过 jquery 发布?

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 个字节)

在此处输入图像描述

4

1 回答 1

5

我最近遇到了这个确切的问题并有解决方案。

核心问题是reader.result传递给reader.onloadby的值readAsBinaryString是字符串,而不是blob。听起来确实很明显,但我也假设我正在处理一个 blob。由于 String 和 Blob 对象都具有切片方法,因此变量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 构造函数的要求)。

Nowslice是一个 blob,因为 Blob.slice() 方法返回一个 Blob 对象,并且可以附加到formdata而不被字符串转换破坏。

于 2013-08-15T19:10:02.347 回答