Getting blob gives 404 error - javascript

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?

Related

Angular JS with PDFTron

I am trying to get a blob as a URL but i get an error on this line :
xhr.send()
The error message is angular.js:13920 Error: Failed to execute 'send' on 'XMLHttpRequest': The object's state must be OPENED.
But in the code I am using xhr.open('GET', blobValue) as shown in my code here
if(someBlobValue){
var viewerElement = $document[0].getElementById('viewer');
var myWebViewer = new PDFTron.WebViewer({
path: 'lib',
pdftronServer: 'https://demo.pdftron.com' // remove
}, viewerElement);
var xhr = new XMLHttpRequest;
xhr.responseType = 'blob';
xhr.onload = function() {
var recoveredBlob = xhr.response;
var reader = new FileReader;
reader.readAsDataURL(recoveredBlob);
};
xhr.open('GET', someBlobValue);
xhr.setRequestHeader('Content-type', 'application/pdf');
xhr.send(); //error here although its open?
//var file = new File([newValue], 'somefile.pdf');
myWebViewer.loadDocument(xhr.response, { filename: 'somefile.pdf'});
Currently i have the document as a blob but i am trying to load it to pdftron library and unfortunately i dont seem to find the myWebViewer.getInstance().loadLocalFile method in the DOM (its undefined).
Would appreciate any pointers as its the first time trying to use pdftron in the angularjs app.
NOTE : This is inside a directive.
You need to wait for the DOM element containing WebViewer to trigger the ready event, for the ReaderControl instance, returned from getInstance(), to be defined.
For example:
$(viewerElement).on('ready', function() {
myWebViewer.getInstance().loadLocalFile(someBlobValue);
});
There is nothing wrong in your code logically,
You just forgot to instantiate the XHR object over here var xhr = new XMLHttpRequest;.
You can correct it by doing this var xhr = new XMLHttpRequest();

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

[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

javascript createObjectURL corrupt file

im using the following javascript to create an object url, the only problem is when loading the url blob:http:///mysite.com/randomhash the file is corrupt.
var audioFile = null;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
audioFile = new Blob([xhttp.response], {type: 'audio/mp3'});
}
};
xhttp.open("GET", "myMp3File.mp3", false);
xhttp.send();
var file = new File([audioFile], "myMp3File.mp3", {type: "audio/mp3", lastModified: Date.now()});
any ideas as to why this would create a blob url with a corrupt mp3 ?
Multiple problems here.
First, you are dealing with asynchronous code. You will need to use a callback in order to use the response of your XHR request.
Then, even if you did so, there are good chances that it will still not work.
This is because the response you get is plain text UTF16 and that some bytes will get mangled by encoding.
The real solution in your case is to directly request the response as a Blob.
You can do so with the XMLHttpRequest.responseType parameter.
var xhttp = new XMLHttpRequest();
xhttp.responseType = 'blob';
xhttp.onload = function(e) {
var blob = xhttp.response;
callback(blob);
};
xhttp.open...
And now in your callback you will be able to create a blobURI directly from this blob.
function callback(blob) {
var url = URL.createObjectURL(blob);
...
Also, if all you want is to display this file, there is no point in creating a File from it, the only web API it would make a difference if it was a File and not just a Blob is Formdata.append method, and even there, it's not that useful.

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

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