Byte array from backend is converted to something else on front-end - javascript

[Route("encrypted")]
[HttpGet]
public sbyte[] Encrypted()
{
var mm = System.IO.File.ReadAllBytes("C:\\test\\" + "fill.txt");
sbyte[] sbt = new sbyte[mm.Length];
Buffer.BlockCopy(mm, 0, sbt, 0, mm.Length);
return sbt;
}
when I hover over with mouse it shows following bytes (which is correct):
But when I check on the front-end (javascript). It becomes a different arrayBuffer:
Here is the front end code:
var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/encrypted/', true);
xhr.responseType = 'arraybuffer'; //i have tried without this line too
xhr.onload = function (e) {
if (this.status === 200) {
console.log("received from server--------");
console.log(e.currentTarget.response);
console.log("received from server-------");
}
};
xhr.send();

You did not ask a specific question, but I think this might help.
Your controller action is responding with JSON. Dumping json to the console shows the same array values on the front-end as does dumping sbt to the console on the back-end. Here is the front-end code that dumps the values.
var xhr = new XMLHttpRequest();
xhr.open('GET', '/api/values', true);
xhr.responseType = 'json';
xhr.onload = function (e) {
if (this.status === 200) {
console.log("json");
const json = e.currentTarget.response;
console.log(json);
console.log("json");
}
};
So, you're sending a JSON array.
As an aside, here are some links about the arraybuffer response type.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data

Related

PHP to javascript JSON.Parse twice

I have this in PHP
$invalid_code_msg = ['error' => 'Invalid purchase code. Please double check your purchase code and try again!'];
throw new Exception(json_encode($invalid_code_msg));
In js:
var xhr = new XMLHttpRequest;
xhr.onerror = function (e) {
console.error(xhr.statusText);
};
xhr.onreadystatechange = function () {
if (this.readyState === 4){
if (this.status === 200) {
var data = JSON.parse(xhr.responseText);
console.log(data, data.error)
//here data is still a string unless I parse it twice?
}
}
};
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("pc=" + purchase_code.value);
I am trying to figure out why data is still a string unless I parse it twice?
data is still a string after first JSON.parse
{"error":"Invalid purchase code. Please double check your purchase code and try again!"}

send the request id with XMLHttpRequest to the serverside

Here I deployed the Get request with Id to pass from the client-side to the server-side to download excel file according to the Id.
client-side js file
$scope.getAUGFile = function () {
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
var params = JSON.stringify({ articleId: articleId });
var url = RESOURCES.USERS_DOMAIN + '/AUGFile/excelDownload/'
xhr.open("GET", url+"?"+params);
xhr.setRequestHeader("authorization", getJwtToken());
xhr.responseType = 'blob';
xhr.onload = function () {
if (this.status === 200) {
saveAs(xhr.response, "mvvAUGExcelTemplate.xls");
}
};
xhr.send(null);
};
server-side js file(spring boot)
#RequestMapping(value = "/AUGFile/excelDownload/{articleId}", method = RequestMethod.GET)
public ResponseWrapper excelGenerateAUG(HttpServletRequest request, HttpServletResponse response,#PathVariable Long articleId){
try{
fileService.downloadAUGFile(request,response,articleId);
return ResponseWrapper.successWithMessage(messageSource.getMessage("success_code",null, Locale.ENGLISH));
} catch (Exception e){
lOG.error(">> Excel file Download error", e);
return ResponseWrapper.failWithMessage(messageSource.getMessage("fail_code", null, Locale.ENGLISH));
}
}
When I execute the client-side function, In the serverside take the articleId value as NULL. How can I fix it? Any advice, help, pointers welcome!
first
console.log(articleId) inside your function to see if its defined and accessible to xhr to send
& try this this instead xhr.open("GET", url+articleId);
or try this
xhr.open("GET", url+"?articleId="+articleId);
I got the correct way of this! It is working now.
client-side js file
$scope.getAUGFile = function () {
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
var url = RESOURCES.USERS_DOMAIN + "/AUGFile/excelDownload/"+articleId;
xhr.open("GET", url);
xhr.setRequestHeader("authorization", getJwtToken());
xhr.responseType = 'blob';
xhr.onload = function () {
if (this.status === 200) {
saveAs(xhr.response, "mvvAUGExcelTemplate.xls");
}
};
xhr.send(null);
};
server-side js file
#RequestMapping(value = "/AUGFile/excelDownload/{articleId}", method = RequestMethod.GET)
public ResponseWrapper excelGenerateAUG(HttpServletRequest request, HttpServletResponse response,#PathVariable("articleId") String articleId){
try{
fileService.downloadAUGFile(request,response,articleId);
return ResponseWrapper.successWithMessage(messageSource.getMessage("success_code",null, Locale.ENGLISH));
} catch (Exception e){
lOG.error(">> Excel file Download error", e);
return ResponseWrapper.failWithMessage(messageSource.getMessage("fail_code", null, Locale.ENGLISH));
}
}

how to instantiate new file object javascript

I'm having troubles instantiating a new file object in javascript.
Here's the general gist of what I'm trying to do. There is client side code that expecting a "file" type object. I need to access the file that's located on the server (game.smc), download it to the local machine and feed it to the client side code.
I did some research and found that creating a new blob object is the first step. But in the code below the blob object remains null and is never getting populated. Does the path in the xhr.open need to have the entire url? Maybe i'm missing an entire concept here not sure.
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open("GET", "/Roms/game.smc");
xhr.responseType = "blob";
xhr.onload = function()
{
blob = xhr.response;
}
xhr.send();
Once I can get the blob object populated I can then do this to convert it to a file object.
function blobToFile(theBlob, fileName) {
theBlob.lastModifiedDate = new Date();
theBlob.name = fileName;
return theBlob;
}
This is what I ended up doing. Shows how to get the blob object as well as convert it to a file type.
function autoLoadGame(fileName) {
var gameLocation = '/Content/Roms/Snes/' + fileName;
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open("GET", gameLocation, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == XMLHttpRequest.DONE) {
var blob = xhr.response;
var file = new File([blob], fileName, { type: '', lastModified: Date.now() });
snes_readfile(file);
}
}
xhr.responseType = "blob";
xhr.send();
}

Getting blob gives 404 error

could someone prompt me - how to save "blob in memory" to a file using Java Script?
e.g. I have in the page next blob-image:
<img src="blob:https%3A//drive.google.com/851b979c-92e9-4ef2-9152-8935f7793630" class="g-img">
and I need to save this blob to a file (png/jpg).
The next code just gives:
GET blob:https%3A//drive.google.com/851b979c-92e9-4ef2-9152-8935f7793630 404 (Not Found)
so it seems, usual way to get the blobs doesn't work here.
Is there any workaround to save this blob-images from browser memory to a file, or, saying more exactly - to get them as a real blob using only "src" tag value?
Thank you.
var srcEl = evt.srcElement;
var CurI = document.getElementsByClassName('g-img');
[].forEach.call(CurI, function (el) {
var xhr = new XMLHttpRequest();
xhr.open('GET', el.src, true);
xhr.responseType = 'arraybuffer'; // xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var myBlob = this.response;
var reader = new window.FileReader();
reader.readAsDataURL(myBlob);
console.log(myBlob);
}
};
xhr.send();
console.log(el.src);
// saveAs(myBlob, 'my2image.png');
}
p.s. to use mediarecorder?

BlobBuilder ruins binary data

I have a problem with BlobBuilder (Chrome11)
I try to obtain an image from server with XHR request. Then i try to save it to local FS with BlobBuilder / FileWriter. Every example on the internet is about working with text/plain mime type and these examples work fine. But when i try to write binary data obtained with XHR, file size becomes about 1.5-2 times bigger than the original file size. And it cannot be viewed in Picasa / Eye Of Gnome.
var xhr = new XMLHttpRequest();
var photoOrigUrl = 'http://www.google.ru/images/nav_logo72.png';
xhr.open('GET', photoOrigUrl, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var contentType = xhr.getResponseHeader('Content-type');
fsLink.root.getFile('nav_logo72.png', {'create': true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
var BlobBuilderObj = new (window.BlobBuilder || window.WebKitBlobBuilder)();
BlobBuilderObj.append(xhr.responseText);
fileWriter.write(BlobBuilderObj.getBlob(contentType));
}, function(resultError) {
console.log('writing file to file system failed ( code ' + resultError.code + ')');
});
});
}
}
xhr.send();
fsLink exists, this is extension.
The problem is that BlobBuilder.append(xhr.responseText) is detecting its argument as a UTF-8 string, which is what XHR returns, and not binary data, which is what it really is. There's a couple of tricks to get the BlobBuilder reading it as binary data instead of string data:
var xhr = new XMLHttpRequest();
var photoOrigUrl = 'http://www.google.ru/images/nav_logo72.png';
xhr.open('GET', photoOrigUrl, true);
// CHANGE 1: This stops the browser from parsing the data as UTF-8:
xhr.overrideMimeType('text/plain; charset=x-user-defined');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
var contentType = xhr.getResponseHeader('Content-type');
fsLink.root.getFile('nav_logo72.png', {'create': true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
// CHANGE 2: convert string object into a binary object
var byteArray = new Uint8Array(xhr.response.length);
for (var i = 0; i < xhr.response.length; i++) {
byteArray[i] = xhr.response.charCodeAt(i) & 0xff;
}
var BlobBuilderObj = new (window.BlobBuilder || window.WebKitBlobBuilder)();
// CHANGE 3: Pass the BlobBuilder an ArrayBuffer instead of a string
BlobBuilderObj.append(byteArray.buffer);
// CHANGE 4: not sure if it's needed, but keep only the necessary
// part of the Internet Media Type string
fileWriter.write(BlobBuilderObj.getBlob(contentType.split(";")[0]));
}, function(resultError) {
console.log('writing file to file system failed ( code ' + resultError.code + ')');
});
});
}
}
xhr.send();
This gave me a file with the same length as what xhr.getResponseHeader('Content-Length') suggests it should have been.
You can use xhr.responseType='arraybuffer' though:
BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder;
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/image.png', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (this.status == 200) {
var bb = new BlobBuilder();
bb.append(this.response); // Note: not xhr.responseText
var blob = bb.getBlob('image/png');
...
}
};
xhr.send();
I think Stoive is spot on but I want to point out that instead of BlobBuilder there is now Blob constructor available that will do the trick
var b = new Blob([byteArray.buffer], {'type': 'application/type'});
I think this is more in keeping with current standards. Thanks much Stoive, very helpful.
Btw XHR2 sets a better way for implementing my task:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://www.google.ru/images/nav_logo72.png', true);
xhr.responseType = 'blob';
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
// xhr.responseBlob is needed blob data
}
}
xhr.send();
The only disappointment is that this is still a bug in Chrome: http://code.google.com/p/chromium/issues/detail?id=52486
XMLHttpRequest cannot load http://www.google.ru/images/nav_logo72.png. Origin file:// is not allowed by Access-Control-Allow-Origin.

Categories

Resources