将数据 URI 转换为文件,然后追加到 FormData

2022-08-30 00:01:02

我一直在尝试重新实现一个HTML5图像上传器,就像Mozilla Hacks网站上的那个一样,但这适用于WebKit浏览器。任务的一部分是从对象中提取图像文件,并将其追加到 FormData 对象以进行上载。canvas

问题是,虽然具有返回图像文件表示形式的函数,但 FormData 对象仅接受来自文件 API 的文件或 Blob 对象。canvastoDataURL

Mozilla解决方案使用以下仅限Firefox的功能:canvas

var file = canvas.mozGetAsFile("foo.png");

...这在 WebKit 浏览器上不可用。我能想到的最好的解决方案是找到一些方法将数据URI转换为File对象,我认为这可能是File API的一部分,但是我无法找到一些东西来做到这一点。

可能吗?如果没有,有什么替代方案吗?


答案 1

在尝试了一些东西之后,我自己设法弄清楚了这一点。

首先,这会将 dataURI 转换为 Blob:

function dataURItoBlob(dataURI) {
    // convert base64/URLEncoded data component to raw binary data held in a string
    var byteString;
    if (dataURI.split(',')[0].indexOf('base64') >= 0)
        byteString = atob(dataURI.split(',')[1]);
    else
        byteString = unescape(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to a typed array
    var ia = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }

    return new Blob([ia], {type:mimeString});
}

从那里,将数据附加到表单以将其作为文件上传很容易:

var dataURL = canvas.toDataURL('image/jpeg', 0.5);
var blob = dataURItoBlob(dataURL);
var fd = new FormData(document.forms[0]);
fd.append("canvasImage", blob);

答案 2

BlobBuilder 和 ArrayBuffer 现已弃用,下面是使用 Blob 构造函数更新的顶级注释代码:

function dataURItoBlob(dataURI) {
    var binary = atob(dataURI.split(',')[1]);
    var array = [];
    for(var i = 0; i < binary.length; i++) {
        array.push(binary.charCodeAt(i));
    }
    return new Blob([new Uint8Array(array)], {type: 'image/jpeg'});
}