Blob from UTF-16 - javascript

I'm trying to get a blob for UTF-16 (I think). Here's the code. I'm not including the full string because it is too long.
const creatBlobUrl = (str) => {
console.log(str)
//?PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\b$\u0000\u0000\u00016\b\u0006\u0000\u0000\u0000???\u0000\u0000\fliCCPICC Profile\u0000\u0000H??W\u0007XS?\u0016?[????\u0002?H\t?\tҫ?\u0010Z\u0004\u0001????\u0004\u0012J?\tAņ????E\u0014+?*??Z\u0000YT?^\u0016??\u0017\u000b*+?bAQTބ\u0004t?W?w?o?̙??;s?\u001d\u00004{?\u0012I.?\u0005#?8_\u001a\u001f\u0011?\u001c???$u\u0000\u0002 \u0001\n0\u0006\b?'????\u0001?????&#\u0014?5'\u0005??????\u00052\u001e\u0000?x?3?2^\u001e??\u0000?\u001bx\u0012i>\u0000D??rj?D?? ֕?\u0000!^??YJ?K?3??i?&1?\r?\u0015\u0000Ԩ\\?4\u000b\u0000??P?,?eA\u001e??\u0010???\"1\u0000??!\u000e?\t?|?\u0015?\u000f?˛??\u0015\u0010?A{\t?0\u001e??\u001dg??3???ܬ!??k#?BE2I.w??Y??-y??A\u001f6?Q???xE????s&G)0\u0015?.qFL???\u0010???ʺ\u0003?R???$?=j̓?a?"
const blob = new Blob([str], {
type: 'image/png',
});
return URL.createObjectURL(blob);
};
First of all, is this even UTF-16. Second what am I doing wrong? BTW, my goal is to pass this url into an anchor tag

Figured it out. #Kaiido you were right. I was in fact losing data over http. I had to encode the data to base64 on the backend before I sent it over http, and then decode it on the front end with something like:
https://stackoverflow.com/a/35713609/11477406

Related

Decode base64 encoded string into xls

I have linked a JSON response on user's request to fetch an excel document, the response is in the manner
{
"format": // file extn ----only xls
"docTitle": //file name
"document" :// base 64 encoded data
}
I tried to handle the API on Frontend by decoding the document key using atob() function.
downloadTemplate() {
this.fetchData.fetchDownloadTemplate().subscribe(
res => {
let docString = atob(res.document);
let format = res.format;
let fileName = res.docTitle;
let file = new Blob([docString], {type: "text/xls"});
let url = URL.createObjectURL(file);
let dwldLink = document.getElementById('template_link');
dwldLink.setAttribute("href", url);
dwldLink.setAttribute("download", fileName);
document.body.appendChild(dwldLink);
dwldLink.click();
},
err => {
console.log(err.responseJSON.message);
})
}
But the data gets corrupted, On doing some research I got to know that atob() decodes using ASCII charset, while I have done the encoding using charset UTF-8.
Can you suggest any alternative method for decoding the data with UTF-8 charset in typescript, as the angular(v4+) project I am working throws error on using JS validators.
While searching for a suitable module which would support Unicode to binary conversion, I came across
https://github.com/dankogai/js-base64#decode-vs-atob-and-encode-vs-btoa
Using Javascript's atob to decode base64 doesn't properly decode utf-8 strings
The Base64.decode() support utob decrpyption.
The module supports angular(v4+), and also add dependencies for Typescript(2)

ASCII to Base64 in JavaScript

I'm trying to pull an image via GET /url.jpg and in the response is the image's ASCII representation. I then take that and try to Base64 encode it so I can display the image via html in an src tag. Here's the code I'm using:
api.getImg()
.then(function(res){
var reader = new window.FileReader();
var data = new Blob([res.data], {type: 'image/jpg'});
reader.readAsDataURL(data);
reader.onloadend = function() {
// sets the base64 encoded image to ng-src via AngularJS
vm.imgVis.viz1.link = reader.result;
}
});
The encoded image is then passed into the ng-src tag and nothing is loaded, broken image. I then take the base64 string to online base64 to image converters and nothing works there either.
Next, I tried directly uploading the image into an 'image to base64' converter and I get a completely new base64 string that works just fine anywhere I use it. Additionally, I turned this new string into an ASCII format and it looks nearly identical to the original GET response, however it appears the unprinted ASCII chars such as NULL are not being represented the same.
I think my issue might be with the ASCII character set. Could that be my problem? I feel like I'm missing a step.
Thanks
Edited to add API call:
function getImg() {
var settings = {
"url": "assets/apple.jpg",
"method": "GET",
"headers": {}
}
return $http(settings)
.then(function(response) {
return response;
})
.catch(function(e) {
return e;
});
}
And here is the actual image:
Apple

URL.createObjectURL and charset UTF-8

i have problem with encoding my text
var description = "jak używać?"
var blob = new Blob([description], {
type: "text/plain;charset=utf-8;"
});
var url = URL.createObjectURL(blob);
console.log(url)
where i enter to url my description isnt same and return jak uĹźywaÄ? What i doing wrong?
Add Byte order mark to the array header.
blob = new Blob(["\ufeff", description]);
https://stackoverflow.com/a/18925211/9867895
https://en.wikipedia.org/wiki/Byte_order_mark
Try:
...
var blob = new Blob([**"\ufeff",** description], {
...
URL.creatObjectUrl doesn't seem to work with raw UTF-8 strings. The solution provided for binary data https://stackoverflow.com/a/36955941/70716 should work. the answers to Creating a Blob from a base64 string in JavaScript also include some additional explanation of the issue and alternative code examples.

Decode Base64 encoded PDF content in browser

We transform HTML to PDF in the backend (PHP) using dompdf. The generated output from dompdf is Base64 encoded with
$output = $dompdf->output();
base64_encode($output);
This Base64 encoded content is saved as a file on the server. When we decode this file content like this:
cat /tmp/55acbaa9600f4 | base64 -D > test.pdf
we get a proper PDF file.
But when we transfer the Base64 content to the client as a string value inside a JSON object (the server provides a RESTful API...):
{
"file_data": "...the base64 string..."
}
And decode it with atob() and then create a Blob object to download the file later on, the PDF is always "empty"/broken.
$scope.downloadFileData = function(doc) {
DocumentService.getFileData(doc).then(function(data) {
var decodedFileData = atob(data.file_data);
var file = new Blob([decodedFileData], { type: doc.file_type });
saveAs(file, doc.title + '.' + doc.extension);
});
};
When we log the decoded content, it seems that the content is "broken", because several symbols are not the same as when we decode the content on the server using base64 -D.
When we encode/decode the content of simple text/plain documents, it's working as expected. But all binary (or not ASCII formats) are not working.
We have searched the web for many hours, but didn't find a solution for this that works for us. Does anyone have the same problem and can provide us with a working solution? Thanks in advance!
This is a example for a on the server Base64 encoded content of a PDF document:
JVBERi0xLjMKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZwovT3V0bGluZXMgMiAwIFIKL1BhZ2VzIDMgMCBSID4+CmVuZG9iagoyIDAgb2JqCjw8IC9UeXBlIC9PdXRsaW5lcyAvQ291bnQgMCA+PgplbmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMKL0tpZHMgWzYgMCBSCl0KL0NvdW50IDEKL1Jlc291cmNlcyA8PAovUHJvY1NldCA0IDAgUgovRm9udCA8PCAKL0YxIDggMCBSCj4+Cj4+Ci9NZWRpYUJveCBbMC4wMDAgMC4wMDAgNjEyLjAwMCA3OTIuMDAwXQogPj4KZW5kb2JqCjQgMCBvYmoKWy9QREYgL1RleHQgXQplbmRvYmoKNSAwIG9iago8PAovQ3JlYXRvciAoRE9NUERGKQovQ3JlYXRpb25EYXRlIChEOjIwMTUwNzIwMTMzMzIzKzAyJzAwJykKL01vZERhdGUgKEQ6MjAxNTA3MjAxMzMzMjMrMDInMDAnKQo+PgplbmRvYmoKNiAwIG9iago8PCAvVHlwZSAvUGFnZQovUGFyZW50IDMgMCBSCi9Db250ZW50cyA3IDAgUgo+PgplbmRvYmoKNyAwIG9iago8PCAvRmlsdGVyIC9GbGF0ZURlY29kZQovTGVuZ3RoIDY2ID4+CnN0cmVhbQp4nOMy0DMwMFBAJovSuZxCFIxN9AwMzRTMDS31DCxNFUJSFPTdDBWMgKIKIWkKCtEaIanFJZqxCiFeCq4hAO4PD0MKZW5kc3RyZWFtCmVuZG9iago4IDAgb2JqCjw8IC9UeXBlIC9Gb250Ci9TdWJ0eXBlIC9UeXBlMQovTmFtZSAvRjEKL0Jhc2VGb250IC9UaW1lcy1Cb2xkCi9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nCj4+CmVuZG9iagp4cmVmCjAgOQowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMDggMDAwMDAgbiAKMDAwMDAwMDA3MyAwMDAwMCBuIAowMDAwMDAwMTE5IDAwMDAwIG4gCjAwMDAwMDAyNzMgMDAwMDAgbiAKMDAwMDAwMDMwMiAwMDAwMCBuIAowMDAwMDAwNDE2IDAwMDAwIG4gCjAwMDAwMDA0NzkgMDAwMDAgbiAKMDAwMDAwMDYxNiAwMDAwMCBuIAp0cmFpbGVyCjw8Ci9TaXplIDkKL1Jvb3QgMSAwIFIKL0luZm8gNSAwIFIKPj4Kc3RhcnR4cmVmCjcyNQolJUVPRgo=
If you atob() this, you don't get the same result as on the console with base64 -D. Why?
Your issue looks identical to the one I needed to solve recently.
Here is what worked for me:
const binaryImg = atob(base64String);
const length = binaryImg.length;
const arrayBuffer = new ArrayBuffer(length);
const uintArray = new Uint8Array(arrayBuffer);
for (let i = 0; i < length; i++) {
uintArray[i] = binaryImg.charCodeAt(i);
}
const fileBlob = new Blob([uintArray], { type: 'application/pdf' });
saveAs(fileBlob, 'filename.pdf');
It seems that only doing a base64 decode is not enough...you need to put the result into a Uint8Array. Otherwise, the pdf pages appear blank.
I found this solution here:
https://github.com/sayanee/angularjs-pdf/issues/110#issuecomment-579988190
You can use btoa() and atob() work in some browsers:
For Exa.
var enc = btoa("this is some text");
alert(enc);
alert(atob(enc));
To JSON and base64 are completely independent.
Here's a JSON stringifier/parser (and direct GitHub link).
Here's a base64 Q&A. Here's another one.

Base64 encode/decode and download content generated in URL

I am generating a string through JavaScript and I need to download it to a text file with a predefined dynamic filename. This way there will be no room for error by employees.
This is obviously not possible in JavaScript due to security issues. However, from what I have read it should be possible with base64 encoding.
I managed to encode the string and open a url with the decoded data. The string has been decoded successfully in this URL. The format is as follows:
var data = 'data:text/plain;base64,'+L_EncodedData;
document.location = data;
I need to open a file dialog with the decoded data so the employees can download the content generated in this URL.
Any help?
Many thanks in advance
If you're still looking for an answer to this, check out my answer here. This is how I would adapt it for your needs.
// Convert the Base64 string back to text.
var txt = atob(data.reportBase64Bytes);
// Blob for saving.
var blob = new Blob([byteString], { type: "text/plain" });
// Tell the browser to save as report.txt.
saveAs(blob, "report.txt");
If you use this, make sure you grab the polyfills that I mention in the other post.
This block is fixed.
window.OpenWindowForBase64 = function(url, callback) {
var image = new Image();
image.src = url;
var w = window.open("");
w.document.write(image.outerHTML);
if (callback) {
callback(url);
}
}

Categories

Resources