XMLHttpRequest how send long base64 string as parameter? - javascript

i am trying to upload some images to a API but the API only accepts the fallowing format to upload the image, base64 string:
curl --location --request POST
"https://api.site.com/send?expiration=600&key=APIKEY"
--form "image=R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
i can send successfully a small image like that:
var req = new XMLHttpRequest();
req.open('POST', 'https://api.site.com/send', true);
var params='key=999999999&image=';
var params2 = 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAVCAYAAABG1c6oAAADEElEQVQ4T21VOUgzURD+1nhERSwsLEQwhZ0H2CkeaCobKwvBG8VKbLWy0VZEwUKLeJJAGiuPwkSwSiEqYmORoGChICheeO+/34R5/0twYNndtzPf++abmbeO6xmy7Pf3F47jyMXnq6sr3NzcyHtxcTEaGhokgqFcs81RwO/vb+Tk5MhFW11dxc7ODvb39/H+/i6B9MnNzZV7S0sLxsbG0NfX9zeg7nh4eIiRkRFhRSsoKMDHx4c8KxjvZPfz84PKykpsbW2hubk5zVgZ8mMkEkF/f78J9Pl8EqSmgPpO1vQh48XFRYyPj/8HXF9fx9DQkDgQhKlzR9VJ9SSY+nDNLgExnM/PT/fu7g51dXV4eHgQIC2KgtlBCmKztYEl5YGBAWxubppUNSUyofiDg4MIBAKy/PLygmg0io2NjQymWm3Hq6BbXl6O19dXIzQD8/PzsbKyIppq5SkFN6EdHBygu7sbb29v+Pr6kjVptUQi4TY2NmZowXQmJycxOzsrjgRi2ly3e3RtbQ3Dw8NmQ/kWj8fdjo4OUwStGvUsLS3NaFzVUtPju7LXtnKOjo7c1tZW0xpawfPzc9TW1gojBjGtvLw88dO16+trVFdXm5Tp55ycnLgcJWrmVdxo0dXVhe3tbTN+NhMF5ACEQiHRVTeVKldVVYG7qWlwT08PlpeXZX7tZn58fMTExATC4XBG4wtDAk5PT2NmZsboZTdxWVkZmpqazIFwcXGBWCwGgmZPDpk6Hn2XAEz79PTUpKyCMz068k7LbnbqSn3pU1FRAcdrCZdUz87O0NnZidvbWwm0NbWlUGD7O0H9fj+8AqdTVqfj42P09vYimUwKE+7KuxZB2doHBjfjibO7u4uampo0oE4Ag5+fnzE3N4eFhQU8PT0ZYAWxTxhmxklaWlpCUVFRuum9ILekpETOPJ59avf399jb25MCpFIpXF5eSlvV19dLw7e3t2N0dBSFhYVSTO0Mnt9uW1sbpqamEAwGpXLZx7rdzHZRVAIdT6myZ+a3wrmcn58XBirDXxOimupG+v/h+z9biQLDtWi4nwAAAABJRU5ErkJggg=='
var param3 = params + params2;
console.log(param3);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.send(param3);
works like a charm, the problem start when i tried to implement that on the current code that converts a captured image from screen in blob format to base64 string, i only get the error from api 'invalid base64 string' using the exact same code above, JS is generating a invalid base64??
using some base64 to image online everything seams ok, but the same string on code only returns invalid base64 string
example of image refused as invalid:
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
how i am converting blob to base64:
console.log("init try upload to Snipboard");
console.log(image_data)
console.log(image_data.imgBlob)
var imgBlob = image_data.imgBlob;
var reader = new FileReader();
var base64data = null;
reader.readAsDataURL(imgBlob);
reader.onloadend = function()
{
base64data = reader.result;
console.log("blob to base64: " + base64data);
var base64Image = base64data.replace(/^.*,/, '');
console.log("blob to base64 pure: " + base64Image);
addon.make.upload(image_data, base64Image);
}
and in addon.make.upload(image_data, base64Image); there is the above XMLHttpRequest code that returns 'invalid base64 string'
anyone has any ideas how convert blob to base64 string....valid?
or what i am doing wrong?

Related

Download base64 encoded file

In React, I uploaded a file using:
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = function() {
let base64data = reader.result;
uploadFile(base64data);
return;
}
This gives me a Base64 encoded text data:application/octet-stream;base64,JVBERi0xLj...
This is fine as when I decode 'JVBERi0xLj...' I get the correct text in case of a text file.
When a download request is made to the server I get the same data back but I'm having a difficulty downloading the file. I receive the same base64 encoded string in the response from the server but unable to open the downloaded file.
I have done the following:
const blob = new Blob([fetchData], { type: 'application/pdf' })
let url = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = blob;
a.download = 'doc.pdf';
a.click();
Any ideas?
Note: The upload file is converted to base64 to avoid any http communication issues.
Solution following your suggestions:
let fetchDataModified = `data:application/pdf;base64,${fetchData }`;
let a = document.createElement("a");
a.href = fetchData;
a.download = 'doc.pdf';
a.click();
When converting to Base64 during upload the data type was set to 'application/octet-stream'. However, when downloading I changed that to 'application/pdf' following Vaibhav's suggestion and used createElement instead of createObjectURL and it worked. Thank you
“data:application/pdf” + the base64 string that you saved into our database

Blob image from database to Java and from Java to Javascript Image

I have Blob, which stored in db and i take it from database with java server like this:
Entity.java
#Column(name = "img")
private Blob img;
public Blob getImg() {
return img;
}
public void setImg(Blob img) {
this.img = img;
}
Repository.java
#Transactional
#Query(value = "SELECT img FROM articles WHERE category = ?", nativeQuery = true)
//Blob findP(String category);
Blob findPic(String category);
Controller.java
#RequestMapping(value="/Pic_test")
#ResponseBody
public Blob getPics() throws SQLException, IOException {
return remindRepository.findPic("Java");
}
Then I receive it with Javascript to image it:
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();
}
toDataURL('http://localhost:8080/articles/Pic_test', function(dataUrl) {
var display = document.getElementById('display');
var url = window.URL.createObjectURL(new Blob([dataUrl]));
var img = new Image();
img.src = url;
document.getElementById("demo").innerHTML = img.src;
})
However, if I call my "img" Blob in java code, i have an error in server, but if I call it byte[], my picture is not shown just.
I can't comment the java part since I know nothing about it, but for the javascript one, what you do is... not correct.
You don't seem to understand what is a data URL, nor what you are doing here.
So a data URL is a string, made of an header and of some file content (data:|mime/type;|file-content).
A data URL is an URL that points to itself, useful to embed data that should normally be served from network.
Quite often, the file content part is encoded as base64, because the URI scheme is limited in its set of allowed characters, and that binary data couldn't be represented in this scheme.
Now let's see what you are doing here...
You are downloading a resource as a Blob. That's good, Blob are perfect objects to deal with binary data.
Then, you read this Blob a data URL. Less good, but I can see the logic, <img> can indeed load images from data URLs.
But then from this data URL string, you create a new Blob! This is completely wrong. The Blob you just created with new Blob([dataUrl]) is a text file, not your image file in any way. So yes, the data is still hidden somewhere in the base64 data which is itself in the data URL, but what your poor <img> will see when accessing the data hooked by the Blob URI is really just text, data:image/png;base64,iVBORw0... and not at all �PNG... like its parsing algo can read.
So the solution is quite easy: get rid of the FileReader step. You don't need it.
var xhr = new XMLHttpRequest();
xhr.open('get', 'https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png');
xhr.responseType = 'blob';
xhr.onload = display;
xhr.send();
function display(evt) {
// we did set xhr.responseType = "blob"
var blob = evt.target.response; // so this is a Blob
// hence, no need for anything else than
var url = URL.createObjectURL(blob);
var img = new Image();
img.src = url;
document.body.appendChild(img);
}
And if I may, all your thing could also just be
document.getElementById('display').src = 'http://localhost:8080/articles/Pic_test';

Use the base64 preview of the binary data response (zip file) in angularjs

I always get this error in the downloaded zip file C:\Users\me\Downloads\test.zip: Unexpected end of archive
My current code is:
var blob = new Blob([data], { // data here is the binary content
type: 'octet/stream',
});
var zipUrl = window.URL.createObjectURL(blob);
var fileName = orderNo;
fileName += '.zip';
downloadFile(null, fileName, null, zipUrl, null); // just creates a hidden anchor tag and triggers the download
The response of the call is a binary (I think). Binary Content Here
But the preview is a base64. Base64 Content. And it is the correct one. The way I verify it is by using this fiddle.
You can refer to the screenshot of the network here
I put the base64 content in this line var sampleBytes = base64ToArrayBuffer(''); And the zip downloaded just opens fine.
Things I have tried so far.
Adding this headers to the GET call
var headers = {
Accept: 'application/octet-stream',
responseType: 'blob',
};
But I get Request header field responseType is not allowed by Access-Control-Allow-Headers in preflight response.
We're using an already ajax.service.js in our AngularJS project.
From this answer
var blob = new Blob([yourBinaryDataAsAnArrayOrAsAString], {type: "application/octet-stream"});
var fileName = "myFileName.myExtension";
saveAs(blob, fileName);
There are other things that I have tried that I have not listed. I will edit the questions once I find them again
But where I'm current at right now. The preview is correct base64 of the binary file. Is it possible to use that instead of the binary? (If it is I will not find the other methods that I've tested) I tried some binary to base64 converters but they don't work.
So I just went and ditched using the ajax.service.js, that we have, for this specific call.
I used the xhr snippet from this answer. I just added the headers necessary for our call: tokens and auth stuff.
And I used this code snippet for the conversion thing.
And the code looks like this:
fetchBlob(url, function (blob) {
// Array buffer to Base64:
var base64 = btoa(String.fromCharCode.apply(null, new Uint8Array(blob)));
var blob = new Blob([base64ToArrayBuffer(base64)], {
type: 'octet/stream',
});
var zipUrl = window.URL.createObjectURL(blob);
var fileName = orderNo;
fileName += ' Attachments ';
fileName += moment().format('DD-MMM-YYYY');
fileName += '.zip';
downloadFile(null, fileName, null, zipUrl, null); // create a hidden anchor tag and trigger download
});
function fetchBlob(uri, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', uri, true);
xhr.responseType = 'arraybuffer';
var x = AjaxService.getAuthHeaders();
xhr.setRequestHeader('auth_stuff', x['auth_stuff']);
xhr.setRequestHeader('token_stuff', x['token_stuff']);
xhr.setRequestHeader('Accept', 'application/octet-stream');
xhr.onload = function (e) {
if (this.status == 200) {
var blob = this.response;
if (callback) {
callback(blob);
}
}
};
return xhr.send();
};
function base64ToArrayBuffer(base64) {
var binaryString = window.atob(base64);
var binaryLen = binaryString.length;
var bytes = new Uint8Array(binaryLen);
for (var i = 0; i < binaryLen; i++) {
var ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
};
return bytes;
}

Cannot convert to System.Byte

I am using trying to send an ajax post request with some text & files. However the accepted file format is base64binary (it is specified by the api to accept the post request)
Am using the below javascript function to convert the image file to a base64:
function encodeImageFileAsURL(){
var filesSelected = document.getElementById("image").files;
if (filesSelected.length > 0)
{
var fileToLoad = filesSelected[0];
var fileReader = new FileReader();
fileReader.onload = function(fileLoadedEvent) {
var srcData = fileLoadedEvent.target.result; // <--- data: base64
var newImage = document.createElement('img');
newImage.src = srcData;
convertedimage = srcData;
document.getElementById("imgTest").innerHTML = newImage.outerHTML;
//alert("Converted Base64 version is "+document.getElementById("imgTest").innerHTML);
console.log("Converted Base64 version is "+document.getElementById("imgTest").innerHTML);
}
fileReader.readAsDataURL(fileToLoad);
}
}
And using a simple ajax call to send the data.
This is the response I am getting from the api:
Cannot convert data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAABmJLR0QA/wD/AP+gvaeTAAAZDElEQVR4nO3deXhV5Z0H8O/vnJsElE1LRRYd0FqXoK3FEbKo6YxLccFWvZCAC0uWoi3aqe10pu0Y22qn1qVVUUkIWgWSEO1Y6IiK9sGaBbRoRVDbqYoiqBVUQCDLPec3f4AtUsDce5b33Hu+n+fxDx9z3vcr5Hzve5Z7DkBERERERERERERERERERERERERERERERERERERERBElpgOQ/wqTi/IH5m0dCsc9TIDBKtZgAQYrdDCAwbt+SkREB+29rSpcAFt2/6sjwCYFNilkk6hssoB3exLu5pXHbNiI2lo3tP8pCgQLIEsVJW/ta+f1P8FxUCiCo0QwSoGRUIwCMByAFXCEbgBvimCdqrwu0HUAXrUc+0X7vTf/vHx5bSrg+ckHLIAscOrlv/qM3dVVBJGTLcGJCpwExecA2Kaz7UcXgJcAXSMqL4rg2YPyCp59/IHLt5sORp/EAoigooo5x0HtYoFbAkgRgOOQ/X9XKQB/BNAuQLvrpFo7WmZuMB0q7rL9lyonlJQ3DFO454vgTFV8GX87Ts9tCrwuwDJVecJN9Hls5YJLt5rOFDcsAEPGld890tZEUi2cD0UxgITpTCYpsF2gy0Wsh3vy8v7nmfuv2Gw6UxywAEJUkmw4Vm23QkWTonKC6TwR5grQ4aq2pNy85mdbpr1jOlCuYgEEbMwFcw7q089OqqIS0BLwzzxd3QCWAlI/3BnwaEvLRMd0oFzCX8aAjJtYd6ZtS7UqLgDQx3SeHPEugGYRrWtrrF5rOkwuYAH4aEz1nLz8bdYlULlaoGNN58lhDoClCvlFR1Plk6bDZDMWgA/KKuYM7lbrGwBmAjjMdJ6Y+Yuq3tm9Q+tXLanZYTpMtmEBeFCUvHu4JPK+A+h0KPqbzhNzGwG9Pd/pmb285aqPTIfJFiyADJyerB+VsvV... to System.Byte.
Parameter name: type ---> Input string was not in a correct format.
Would anyone tell me about the way or approach to fix this?
Thank you in advance.

Create data URIs on the fly?

Is there a script (javascript / client side). That create data URIs on the fly. Now i create data URIs with a online base64 creator. And then put that output in the css file. But when i changing the images. Its a lot of work to do it. Is there a script, that can do it for me.?
The modern browsers now have good support for base64 encoding and decoding. There are two functions respectively for decoding and encoding base64 strings:
atob() decodes a string of base-64 data
btoa() creates a base-64 encoded ASCII string from a "string" of binary data
This let's you create data uri's easily i.e
var longText = "Lorem ipsum....";
var dataUri = "data:text/plain;base64," + btoa(longText);
//a sample api expecting an uri
d3.csv(dataUri, function(parsed){
});
As a complete solution to your scenario, you can use fetch to get a blob representation of your image, and then use FileReader to convert the blob in its base64 representation
// get an image blob from url using fetch
let getImageBlob = function(url){
return new Promise( async resolve=>{
let resposne = await fetch( url );
let blob = resposne.blob();
resolve( blob );
});
};
// convert a blob to base64
let blobToBase64 = function(blob) {
return new Promise( resolve=>{
let reader = new FileReader();
reader.onload = function() {
let dataUrl = reader.result;
resolve(dataUrl);
};
reader.readAsDataURL(blob);
});
}
// combine the previous two functions to return a base64 encode image from url
let getBase64Image = async function( url ){
let blob = await getImageBlob( url );
let base64 = await blobToBase64( blob );
return base64;
}
// test time!
getBase64Image( 'http://placekitten.com/g/200/300' ).then( base64Image=> console.log( base64Image) );
One way is to make a Blob of an object, and then use URL.createObjectURL()
let a = URL.createObjectURL(new Blob([JSON.stringify({whatever: "String..."}, null, 2)]))
console.log(a)

Categories

Resources