2017-08-02 5 views
2

Ich verwende native Javascript-Methoden, um Bilder auf einen Express-Server hochzuladen. In meiner Anwendung gibt es zwei Arten von Uploads.Hochladen von Bild in Safari funktioniert nicht

  1. Hochladen von Dateiobjekt genommen von <input type=file>
  2. Hochladen Bild gezeichnet genommen von <canvas>

Ich habe keine Probleme mit dem ersten Typ Lade für Firefox, Chrome und Safari. Das Datei-Image wird korrekt hochgeladen und ich kann die Datei anzeigen, die auf den Server hochgeladen wurde.

Allerdings habe ich ein Problem mit der zweiten Art von Upload. Ich kann die Datei nicht korrekt mit einem Safari-Browser hochladen. Es wird immer eine 0-Byte-Datei auf dem Server ergeben. Aber es funktioniert gut auf Firefox und Chrome.

Hier sind Schnipsel meines Codes:

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); 
}; 

Express-Schnipsel:

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)); 
     }); 
    }); 
}); 

Also, was ich tue, ist die base64 von der Leinwand immer toDataURL() verwenden und es dann in ein Datei-Objekt konvertieren und dann an das Objekt FormData anhängen, bevor Sie es mit XMLHttpRequest auf den Server hochladen.

Diese Methode funktioniert für Chrome und Firefox, aber nicht für Safari. Es wird überhaupt kein Fehler angezeigt. Weiß jemand warum?

+0

Warum versuchen Sie, Daten-URI in Datei-Objekt zu konvertieren? – guest271314

+0

Es ist eigentlich eine Anforderung aus dem Backend, das Bild in einem multipart/form-data zu senden. Ich habe versucht, den Daten-URI zu den FormData hinzuzufügen, und es funktioniert nicht. Musste es in eine Datei umwandeln, um es an die formData anhängen zu können. –

Antwort

0

Es sollte kein Problem mit canvas.toBlob() geben, wenn kein Problem mit <input type=file> auftritt. File Objekt erbt von Blob Objekt. FormData konvertiert Blob in File Objekt.

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") 
+0

danke! das funktioniert! Aber es gibt keine ToBlob-Methode auf Leinwand in Safari, musste eine Polyfill dafür hinzufügen. –

Verwandte Themen