在 Safari 中上传图片不起作用

Uploading Image in Safari not working

我正在使用本机 javascript 方法将图像上传到 Express 服务器。我的应用程序中有两种类型的上传。

  1. 正在上传取自 <input type=file>
  2. 的文件对象
  3. 正在上传从 <canvas>
  4. 中绘制的图像

我对 firefox、chrome 和 safari 的第一种上传没有问题。文件图片正在正确上传,我可以查看上传到服务器的文件。

但是,我对第二种上传有问题。我无法使用 Safari 浏览器正确上传文件。它总是会在服务器中产生一个 0 字节的文件。但它在 firefox 和 chrome.

上都运行良好

以下是我的代码片段:

const content = canvasRef.toDataURL()
const file = convertDataURLToFile(content, "signature.png");
fileUploadHelper(file, fileUploadUrl(), "signature");

function convertDataURLToFile (file, fileName) {
    const blobBin = window.atob(file.split(",")[1]);
    const array = [];
    for (var i = 0; i < blobBin.length; i++) {
        array.push(blobBin.charCodeAt(i));
    }
    return new window.File([new Uint8Array(array)], fileName, {type: "image/png"});
};

function fileUploadHelper (file, url, inputType) {
    const xhr = new window.XMLHttpRequest();
    const formData = new window.FormData();
    formData.append("file", file);
    xhr.open("POST", `${url}&documentType=${inputType}`);
    xhr.send(formData);
};

表达片段:

app.post("/fileUpload", function (req, res) {
    req.pipe(req.busboy);
    req.busboy.on("file", function (fieldname, file, filename) {
        file.on("data", function (data) {
            console.log(data.length);
        });
        var fstream = fs.createWriteStream("./tempFiles/" + filename);
        file.pipe(fstream);
        fstream.on("close", function () {
            var response = clone(baseResponse);
            response.status = SUCCESS;
            return res.end(JSON.stringify(response));
        });
    });
});

所以我正在做的是使用 toDataURL() 从 canvas 获取 base64,然后将其转换为文件对象,然后在上传之前将其附加到 FormData 对象使用 XMLHttpRequest.

到服务器

此方法适用于 Chrome 和 Firefox,但不适用于 Safari。根本不会在任何地方抛出错误。有谁知道为什么?

如果使用 <input type=file> 没有问题,那么使用 canvas.toBlob() 应该没有问题。 File 对象继承自 Blob 对象。 FormDataBlob 转换为 File 对象。

    canvas.toBlob(function(blob) {
       var formData = new FormData();
       // `xhr` settings
const xhr = new window.XMLHttpRequest();
       const formData = new window.FormData();
       // if you want to convert `blob` to `File`
       // const file = new window.File([blob], "signature.png", {type: blob.type});
       formData.append("file", blob /* or `file` */);
       xhr.open("POST", `${url}&documentType=${inputType}`);
       xhr.send(formData);
    }, "image/png")