通过jQuery.ajax使用FormData发布Blob

Bri*_*n D 8 ajax jquery html5

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

如何附加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
    });
}
Run Code Online (Sandbox Code Playgroud)

所有非blob键/值都在请求中,甚至是blob的键......但不是blob数据.

缺失数据

有趣的是,当我使用Firefox而不是Chrome发布时,我在那里获得了一些数据..但不多(这应该是高达2 MB的数据...它是7个字节)

在此输入图像描述

Ste*_*air 5

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

核心问题是,价值reader.result传递给reader.onloadreadAsBinaryString一个字符串,而不是一个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);
}
Run Code Online (Sandbox Code Playgroud)

(该数组是Blob构造函数的要求).

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