web-dev-qa-db-fra.com

Comment convertir dataURL en objet fichier en javascript?

J'ai besoin de convertir un dataURL en un objet File en Javascript afin de l'envoyer via AJAX. C'est possible? Si oui, dites-moi comment.

36
kapv89

Si vous devez l'envoyer via ajax, il n'est pas nécessaire d'utiliser un objet File, seuls les objets Blob et FormData sont nécessaires.

Comme je l'ai vu, pourquoi ne pas simplement envoyer la chaîne base64 au serveur via ajax et la convertir en serveur binaire, en utilisant base64_decode par exemple? Quoi qu'il en soit, le code conforme aux normes de cette réponse fonctionne dans Chrome 13 et nightlies WebKit:

function dataURItoBlob(dataURI) {
    // convert base64 to raw binary data held in a string
    // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
    var byteString = atob(dataURI.split(',')[1]);

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

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

    //Old Code
    //write the ArrayBuffer to a blob, and you're done
    //var bb = new BlobBuilder();
    //bb.append(ab);
    //return bb.getBlob(mimeString);

    //New Code
    return new Blob([ab], {type: mimeString});


}

Ensuite, ajoutez simplement le blob à un nouvel objet FormData et postez-le sur votre serveur en utilisant ajax:

var blob = dataURItoBlob(someDataUrl);
var fd = new FormData(document.forms[0]);
var xhr = new XMLHttpRequest();

fd.append("myFile", blob);
xhr.open('POST', '/', true);
xhr.send(fd);
47

BlobBuilder est obsolète et ne devrait plus être utilisé. Utilisez Blob au lieu de l'ancien BlobBuilder. Le code est très propre et simple.

L'objet fichier est hérité de l'objet Blob. Vous pouvez les utiliser tous les deux avec un objet FormData.

function dataURLtoBlob(dataurl) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type:mime});
}

utilisez la fonction dataURLtoBlob () pour convertir dataURL en blob et envoyer ajax au serveur.

par exemple:

var dataurl = 'data:text/plain;base64,aGVsbG8Gd29ybGQ=';
var blob = dataURLtoBlob(dataurl);
var fd = new FormData();
fd.append("file", blob, "hello.txt");
var xhr = new XMLHttpRequest();
xhr.open('POST', '/server.php', true);
xhr.onload = function(){
    alert('upload complete');
};
xhr.send(fd);

Une autre façon:

Vous pouvez également utiliser fetch pour convertir une URL en objet fichier (l'objet fichier a la propriété name/fileName, c'est différent de l'objet blob)

Le code est très court et facile à utiliser. (works in Chrome and Firefox)

//load src and convert to a File instance object
//work for any type of src, not only image src.
//return a promise that resolves with a File instance

function srcToFile(src, fileName, mimeType){
    return (fetch(src)
        .then(function(res){return res.arrayBuffer();})
        .then(function(buf){return new File([buf], fileName, {type:mimeType});})
    );
}

Exemple d'utilisation 1: il suffit de convertir en objet fichier

srcToFile(
    'data:text/plain;base64,aGVsbG8Gd29ybGQ=',
    'hello.txt',
    'text/plain'
)
.then(function(file){
    console.log(file);
})

Exemple d'utilisation 2: conversion en objet fichier et téléchargement sur le serveur

srcToFile(
    'data:text/plain;base64,aGVsbG8Gd29ybGQ=',
    'hello.txt',
    'text/plain'
)
.then(function(file){
    console.log(file);
    var fd = new FormData();
    fd.append("file", file);
    return fetch('/server.php', {method:'POST', body:fd});
})
.then(function(res){
    return res.text();
})
.then(console.log)
.catch(console.error)
;
40
cuixiping

Après quelques recherches, je suis arrivé sur celui-ci:

function dataURItoBlob(dataURI) {
    // convert base64 to raw binary data held in a string
    // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
    var byteString = atob(dataURI.split(',')[1]);
    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
    // write the bytes of the string to an ArrayBuffer
    var ab = new ArrayBuffer(byteString.length);
    var dw = new DataView(ab);
    for(var i = 0; i < byteString.length; i++) {
        dw.setUint8(i, byteString.charCodeAt(i));
    }
    // write the ArrayBuffer to a blob, and you're done
    return new Blob([ab], {type: mimeString});
}

module.exports = dataURItoBlob;
0
EpokK