I can't figure out how to display image bytes returned from a web api in an html Image. This is how the data looks in firefox console (truncated for brevity):
������JFIF�������������C����������������������...
I've tried to use data:image/jpeg;base64, " + btoa(data) as image src, I get String contains an invalid character error. When I use btoa(unescape(encodeURIComponent(data)))instead of btoa I get no errors, but the image is not displayed. The Content-Type of the response is image/jpeg.
The image is rendered correctly in Fiddler.
Any ideas how to get the image to display the data?
I've got it working. The problem was that I used Jquery $.ajax to get the image data. Jquery automatically converted the received bytes into an UTF-16 string and passed that string into the success callback.
If I used basic XMLHttpRequest I was able to render the received image in html, like this:
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.responseType = "arraybuffer";
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onload = function() {
var byteArray = new Uint8Array(xhr.response);
var base64Data = btoa(String.fromCharCode.apply(null, byteArray));
image.attr("src", "data:image/jpeg;base64, " + base64Data);
};
xhr.send(jsonPayload);
Related
The server is sending me an image through an API call. I'm unsure how to convert it to base64 and show as image src. The FileReader's readAsDataURI says it's not type of blob. However, the browser's network panel does preview the image correctly. The server is not sending a 'Content-Type' header with the response, can this be the issue? screenshot of the response
If the chrome dev tool shows the image correctly then it is a valid blob file.
You just need to set the response type in your request and also You can use the createObjectURL to generate the image
Here is a sample snippet
function response(e) {
var urlCreator = window.URL || window.webkitURL;
console.log(this.response);
var imageUrl = urlCreator.createObjectURL(this.response);
document.querySelector("#image").src = imageUrl;
}
function GetImageBlob(){
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://secret/upload/IMG_1_201810220930_1.jpg");
//Set Header if is required by the api
xhr.setRequestHeader("Authorization","Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDAyMTg5MDYsImlzcyI6Imh0dHA6Ly9yc3YtZGV2LmJsb3RvY29sLnRlY2gvYWRtaW4iLCJhdWQiOiJodHRwOi8vcnN2LWRldi5ibG90b2NvbC50ZWNoL2FkbWluIn0.YTHKhrl05PWDWCkHB1Nw7yW5166NiyGG3kZ_7SWfT1I");
xhr.responseType = "blob";
xhr.onload = response;
xhr.send();
}
GetImageBlob();
I am trying to send pdf file from my express server using the client when requested like this:
res.setHeader('Content-Type', 'application/pdf');
res.setHeader('Content-Disposition', 'attachment; filename=test.pdf');
fs.createReadStream('test.pdf').pipe(res);
And then on the client side I am trying to download it by taking the resulting string converting it to a url and downloading from there.
var blob = new Blob[pdfString], { type: 'application/pdf' });
var url = window.URL;
var downloadUrl = url.createObjectURL(blob);
However the resulting file is two empty pages and I beleive think it might be because the resulting file is url is to large? If anyone could figure out whats wrong here or tell me of a better way to do it that would be awesome.
I was able to figure it out using XMlHttpRequest:
var req = new XMLHttpRequest();
req.open('GET', path , true);
req.responseType = "arraybuffer";
req.onload = (event) => {
downloadPdf(req.response); //This is where I convert to blob
}
req.send();
I'm writing a chrome extension content script which will embed itself on some pages, and when there are certain file type links (.doc, .torrent, etc) it will download that file, and then do a file POST to a python web server which will save that file. The python server is working, and handles a normal multipart/form-data POST request, and successfully saves the file when I use the html interface I wrote for it.
I have javascript downloading the file properly:
var req = new XMLHttpRequest();
req.open('GET', 'http://foo.com/bar.torrent', false);
req.overrideMimeType('text/plain; charset=x-user-defined');
req.send(null);
if (req.status != 200) return '';
var response = req.responseText;
And then when I try to create a POST request and upload it
// Define a boundary, I stole this from IE but you can use any string AFAIK
var boundary = "---------------------------7da24f2e50046";
var xhr = new XMLHttpRequest();
var body = '--' + boundary + '\r\n'
// Parameter name is "file" and local filename is "temp.txt"
+ 'Content-Disposition: form-data; name="upfile";'
+ 'filename="temp.torrent"\r\n'
// Add the file's mime-type
+ 'Content-type: application/bittorrent\r\n\r\n'
+ response + '\r\n';
//+ boundary + '--';
xhr.open("POST", "http://python.server/", true);
xhr.setRequestHeader(
"Content-type", "multipart/form-data; boundary="+boundary
);
xhr.onreadystatechange = function ()
{
if (xhr.readyState == 4 && xhr.status == 200)
alert("File uploaded!");
}
xhr.send(body);
It thinks that it uploaded successfully, but when I try to open the file it says the data is corrupted. I think this is some kind of encoding issue, but I'm not 100% sure.
Any thoughts would be very helpful.
Your upload method does not work, because all binary characters are encoded as UTF-8. I posted the explanation and solution in an answer at this question.
In your case, you don't need to manually create the post data. Request the initial data in a smart way, and use the FormData object to post the binary data. For instance:
var x = new XMLHttpRequest();
x.onload = function() {
// Create a form
var fd = new FormData();
fd.append("upfile", x.response); // x.response is a Blob object
// Upload to your server
var y = new XMLHttpRequest();
y.onload = function() {
alert('File uploaded!');
};
y.open('POST', 'http://python/server/');
y.send(fd);
};
x.responseType = 'blob'; // <-- This is necessary!
x.open('GET', 'http://foo.com/bar.torrent', true);
x.send();
Note: I replaced false with true at the initial request. Avoid using synchronous XMLHttpRequest when it's also possible to asynchronously create the request.
If you don't understand the answer, here are more examples with thorough explanations:
XMLHttpRequest: Multipart/Related POST with XML and image as payload - FormData is not used, but the post data is manually created instead.
Upload a File in a Google Chrome Extension - A sample Chrome extension which uses Web Workers (with a FormData polyfill) to upload files
Google chrome rehost image extension - Scrapes an image from the page, and upload the image to imgur using a Chrome extension.
I'm trying to make a little script to rehost pictures on the web on imgur.
This is called Image Sideloading and you only need to point the browser to http://api.imgur.com/2/upload?url= + Picture's Url
It doesn't return any XML or JSON response so I can't parse it to get the img URL.
But I think I found a way to do this but can't get it to work properly. Here's the code I'm using.
$(document).ready(function() {
$("#button").click(function() {
str = $("input").val().toString();
link = "http://api.imgur.com/2/upload?url=" + str;
var xhr = new XMLHttpRequest();
xhr.open("GET", link);
xhr.send();
var headers = xhr.getAllResponseHeaders().toLowerCase;
alert(headers);
});
});
And looking at Google Chrome's console these are the results generated after the script runs.
I am not allowed to post images yet so here's a link to the results: http://i.imgur.com/xCyIP.png
I need to somehow access that 4th response header because even though this method doesn't return any parsable XML or JSON response that link is the uploaded img's URL which is all I need.
So is there a way to access that info? Why is it cancelled?
Thanks everyone!
Well, the API must return something, else it is useless.
Actually, http://api.imgur.com/examples advises you to do something like:
var xhr = new XMLHttpRequest();
xhr.open("GET", link);
xhr.onload = function() {
var url = JSON.parse(xhr.responseText).upload.links.imgur_page;
alert(url);
}
xhr.send();
Edit. OK, I got it. Normally, the above code should work, but I think imgur is facing a problem. I will report the bug.
While the bug is still there, here is a dirty solution to serve your needs:
var xhr = new XMLHttpRequest();
xhr.open("GET", link);
xhr.onload = function() {
html = xhr.responseText;
alert(html.substr(html.indexOf('http://i.imgur.com/') + 19, 5));
}
xhr.send();
You code wasn't working because you weren't waiting for the answer. You have to catch it through a callback function.
Edit. The above code only works locally. As you're using jQuery, let me introduce the shortcut $.post:
$(document).ready(function() {
$("#button").click(function() {
$.post('http://api.imgur.com/2/upload.json', {
key: 'ec575de603b936e54c2b4a9f232d537e',
image: $("input").val().toString()
}, function(data) {
alert(data.upload.image.hash);
});
});
});
http://jsfiddle.net/Le_Sphinx/rEfdS/
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Getting BLOB data from XHR request
I try to get an image from my server dynamically, but the XMLHTTPRequest returns null in the response. The Google Chrome network tool tells me that he loaded the day1.jpg, but the blob variable is null...
var xhr = new XMLHttpRequest(), blob;
xhr.open("GET", "day1.jpg", true);
// Set the responseType to blob
xhr.responseType = "blob";
xhr.addEventListener("load", function () {
if (xhr.status === 200) {
console.log("Image retrieved");
blob = xhr.response;
console.log("blob: " + blob);
}
}, false);
// Send XHR
xhr.send();
The output is:
Image retrieved
blob: null
The reason is a bug on the Chrome side (also available on v18). Reported here
why use ajax to load the image (as far as I know you can't http://www.mail-archive.com/discuss#jquery.com/msg00377.html)? You can just dynamically generate an image element and set the src attribute to the image on your server.
var i = new Image();
i.onload = function()
{
//do the stuff you need to do once it loads here
}
i.src = "day1.jpg";
Use the console to inspect the xhr object and see if it's being populated at all
I doubt that you can load images from the server dynamically, instead what you can do is update the image source dynamically and tell from whci location shoul the image be fetched/loaded