Convert Data Uri to File Then Append to Formdata

Convert Data URI to File then append to FormData

After playing around with a few things, I managed to figure this out myself.

First of all, this will convert a dataURI to a 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});
}

From there, appending the data to a form such that it will be uploaded as a file is easy:

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

How to append a file to a FormData() from a URL or file on server rather than a file input

I read your question a second time. If I understand correctly you need to send a cross-domain AJAX request to stripe.com, so you are not controlling the PHP code on the server side, right?

SHORT ANSWER:

The easiest way would be to do your form check in Javascript instead of PHP, so you won't need to go back and "lose" the selected input file.


... BUT if you really need/want to send a cross-domain file using only its URL,

then you'll need to convert Data URI to File then append to FormData :

1/ Get you image base64 value

function toDataUrl(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
callback(reader.result);
}
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', url);
xhr.responseType = 'blob';
xhr.send();
}

2/ Convert the base64 image to Blob :

function DataURIToBlob(dataURI: string) {
const splitDataURI = dataURI.split(',')
const byteString = splitDataURI[0].indexOf('base64') >= 0 ? atob(splitDataURI[1]) : decodeURI(splitDataURI[1])
const mimeString = splitDataURI[0].split(':')[1].split(';')[0]

const ia = new Uint8Array(byteString.length)
for (let i = 0; i < byteString.length; i++)
ia[i] = byteString.charCodeAt(i)

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

3/ Send you Blob with FormData :

const file = DataURIToBlob(imgBase64)
const formData = new FormData();
formData.append('upload', file, 'image.jpg')

Sources :

  • CONVERT Image url to Base64
  • https://pretagteam.com/question/how-to-append-an-image-from-url-to-a-formdata-javascript
  • https://www.geeksforgeeks.org/how-to-convert-data-uri-to-file-then-append-to-formdata/

Edit:

You could speed up phase 1 and 2 by using the Fetch API to get the image Blob directly.

(WARNING: not compatible with IE)

Source : How to get a File() or Blob() from an URL in javascript?

Convert Data URI to File

You can convert the canvas to a Blob, and then upload that.

To convert to a Blob, try this script: https://github.com/blueimp/JavaScript-Canvas-to-Blob

Then you can use canvas.toBlob instead of canvas.toDataURL.

Then to upload it, you need to use FormData

canvas.toBlob(function(blob){
var form = new FormData(),
request = new XMLHttpRequest();

form.append("image", blob, "filename.png");
request.open("POST", "/upload", true);
request.send(form);
}, "image/png");

This is un-tested, but should work.

How to convert dataURL to file object in javascript?

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

Append all data from form (including files) to FormData

You're overcomplicating things. You don't need to think about the individual elements at all. Just give the FormData object your form and let it take care of finding the data in it.

var form = document.getElementById("MyForm");
var data = new FormData(form);
xhr.send(data);

Note that PHP requires special naming conventions when you have multiple values for the same field name.

name="PhotoToUpload" needs to be name="PhotoToUpload[]"



Related Topics



Leave a reply



Submit