Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert dataURL to file object in javascript?

I need to convert a dataURL to a File object in Javascript in order to send it over using AJAX. Is it possible? If yes, please tell me how.

like image 956
kapv89 Avatar asked Jul 27 '11 19:07

kapv89


2 Answers

If you need to send it over ajax, then there's no need to use a File object, only Blob and FormData objects are needed.

As I sidenote, why don't you just send the base64 string to the server over ajax and convert it to binary server-side, using PHP's base64_decode for example? Anyway, the standard-compliant code from this answer works in Chrome 13 and WebKit nightlies:

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

Then just append the blob to a new FormData object and post it to your server using 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); 
like image 85
Matthew Avatar answered Sep 30 '22 17:09

Matthew


The BlobBuilder is deprecated and should no longer be used. Use Blob instead of old BlobBuilder. The code is very clean and simple.

File object is inherit from Blob object. You can use both of them with FormData object.

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

use dataURLtoBlob() function to convert dataURL to blob and send ajax to server.

for example:

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

Another way:

You can also use fetch to convert an url to a file object (file object has name/fileName property, this is different from blob object)

The code is very short and easy to use. (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});})     ); } 

Usage example 1: Just convert to file object

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

Usage example 2: Convert to file object and upload to server

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) ; 
like image 36
cuixiping Avatar answered Sep 30 '22 19:09

cuixiping