Raw response of a image/png resonpse - javascript

I am getting a response body with raw response, which is supposed to respresent a png image. My question is how to decode this and make it a renderable.
PS: when I am use postman to test this, I realized that Postman can render this raw string, and I am wondering how it does it.
�PNG
IHDR�X:�(� pHYs���o�d
IDATx���\�w����v,J�L�2b�_٬�N��d��0|�cmDN�6�y.�q�{�Iӌ�hsnNcl��g~/;"vʯ�m�('}�Q9��q�P(G:�������z=���q��|=_�\�p�""""""�p�w""""""b
�""""""J�PDDDDD�A)������8(B�#("""""�EDDDDD���������R
qP
�""""""J�PDDDDD�A)������8(B�#("""""�EDDDDD���������R
[...]

After a few hours of googling, I finally figured out the issue:
Essentially, the response from my REST call actually contains blob type of the png image. So to properly render it, we don't have to base64 the blob, instead it is natively supported by html5. The problem I was facing is that this blob is not supported by jQuery ajax call, hence higher level libraries like axios does NOT support it either.
For simplicity, to demo how this works, I would use jQuery:
<html lang="en">
<head>
<meta charset="utf-8">
<title>Blob image/png demo</title>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
<form action="/" id="invokeBlob">
<input type="submit" value="Invoke It!">
</form>
<!-- the result of the blob will be rendered inside this div -->
<div id="imgcontainer"></div>
<script>
// Attach a submit handler to the form
$( "#invokeBlob" ).submit(function( event ) {
// Stop form from submitting normally
event.preventDefault();
var url = "https://YOUR-DOMAIN/charts";
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = "blob";
xhr.setRequestHeader("Authorization", "Bearer XXX-YOUR-JWT-TOKEN")
xhr.setRequestHeader("Accept", "image/png");
xhr.onload = function() {
if (this.status == 200) {
var blob = this.response;
var img = document.createElement("img");
img.onload = function(e) {
window.URL.revokeObjectURL(img.src);
};
img.src = window.URL.createObjectURL(blob);
$("#imgcontainer").html(img);
}
}
xhr.send();
});
</script>
</body>
</html>

Related

Why doesn't ajax show the content of updated JSON?

I am new to JavaScript. What I want to do is sending an ajax request and get the content of a JSON file and simply put it into a div. This is my code:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<title>Ajax 1 - Text File</title>
</head>
<body>
<button id="button">Get Text File</button>
<br><br>
<div id="text"></div>
<script>
document.getElementById("button").addEventListener('click', loadText);
function loadText(){
var xhr = new XMLHttpRequest();
xhr.open('GET', 'users.json', true);
xhr.onload = function(){
if(this.status == 200){
document.getElementById('text').innerHTML = this.responseText;
}
else if (this.status == 404){
document.getElementById('text').innerHTML = 'not found';
}
}
xhr.send();
}
</script>
</body>
</html>
And this is users.json:
[
{
"id":1,
"name":"Rick",
"email":"rick#gmail.com"
},
{
"id":2,
"name":"Negan",
"email":"negan#gmail.com"
}
]
This works fine. But, when I manually updated users.json and change it and refresh the browser, the browser does not show the updated json. It still gives me the previous json file. How can I fix it?
It is possible that the browser is responding with a cached response.
Try appending 'timestamp' so that every time a new request would be made to the server to get updated contents.
document.getElementById("button").addEventListener('click', loadText);
function loadText() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'users.json?ts=' + Date.now(), true);
xhr.onload = function() {
if (this.status == 200) {
document.getElementById('text').innerHTML = this.responseText;
} else if (this.status == 404) {
document.getElementById('text').innerHTML = 'not found';
}
}
xhr.send();
}
<button id="button">Get Text File</button>
<br><br>
<div id="text"></div>
As you have included jQuery in your webpage, I would recommend to use jQuery version of ajax. To disallow the use of the cached results, set cache to false.
$.ajax({
url: 'myurl',
type: 'GET',
dataType: 'json',
data: jsonDataObject,
cache: false, // Appends _={timestamp} to the request query string
success: function(data) {
// data is a json object.
}
});
try check the disable cache checkbox on network panel of the dev tool.
it might be caused by the cache of your web server
You need to pass header
content_type="application/json"

Why can't I get the XML document from this link, and why in the string i can get all tag brackets become quotation marks?

I' m working on an assignment that requires me to get data from the URL http://quotes.rest/qod?category=inspire ; specifically, the contents of the <quote> and <author> tags.
To do this I use a XMLHttpRequest; problem is, if I set xhr.responseType = 'document' (or if I use xhr.responseXML ), the variable I try to put the request in becomes null.
If I use xhr.responseText, I get the correct representation of the site in string form, and I could solve the problem working with that, but that's not how I'm intended to do it. I tried to parse the string into a XML document, but in the string I get from xhr.responseText every <> bracket is replaced with a ", causing the parsing to produce an incorrect XML document.
Please help me solve one of these two problems, either getting the XML document or the string in the correct XML syntax, thank you very much.
var doc;
var x;
function submit() {
var xhr = new XMLHttpRequest();
// here adding xhr.responseType = 'document' doesn' t change the outcome
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
doc = xhr.responseXML;
}
}
xhr.open('get', 'http://quotes.rest/qod?category=inspire', true);
xhr.send();
}
function trial(){
x = doc.getElementsByTagName("quote")[0].childNodes[0].nodeValue;
//by this point doc is null, so I get an error here
console.log( x );
}
<h5>Press to see the quote of the day:</h5>
<input type="submit" value="Start" onclick="submit()">
<!-- the first button fetches the data from the URL -->
<input type="submit" value="Trial" onclick="trial()">
<!-- the second one is supposed to show on console the quote -->
It's interesting that if you send Accept request header like this
xhr.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml")
then it responses as XML.
var doc;
var x;
function submit() {
var xhr = new XMLHttpRequest();
// here adding xhr.responseType = 'document' doesn' t change the outcome
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
doc = xhr.responseXML;
}
}
xhr.open('get', 'http://quotes.rest/qod?category=inspire', true);
xhr.setRequestHeader("Accept", "text/html,application/xhtml+xml,application/xml");
xhr.send();
}
function trial(){
x = doc.getElementsByTagName("quote")[0].childNodes[0].nodeValue;
//by this point doc is null, so I get an error here
console.log( x );
}
<h5>Press to see the quote of the day:</h5>
<input type="submit" value="Start" onclick="submit()">
<!-- the first button fetches the data from the URL -->
<input type="submit" value="Trial" onclick="trial()">
<!-- the second one is supposed to show on console the quote -->

How to make my HTTP request behave the same as a form

I'd need some help with my HTTP request. Here's the setup:
A webpage load an image to a form and send it to a python server running bottle (with the form or a custom http request)
Bottle receive the file, give it as an input for a python script, receive the result and return it to the webpage
On bottle's website there's an example with a form: https://bottlepy.org/docs/dev/tutorial.html#file-uploads I've tried it and it works. Here's the code I used:
<html>
<head>
</head>
<body>
<form action="http://localhost:8080/solve" method="POST" enctype="multipart/form-data" norm="form" id='myForm'>
Select a file: <input type="file" name="upload"/>
<input type="submit" value="Start upload" />
</form>
</body>
</html>
In bottle I have:
#route('/solve', method='POST')
def solve():
file = request.files.get('upload')
name, ext = os.path.splitext(file.filename)
if ext not in ('.png','.jpg','.jpeg'):
return 'File extension not allowed.'
print(file.name)
resolved = sudoku.solve(file.file)
return str(resolved)
This "works", but the form redirects me to localhost:8080 and it's not what I want. I tried putting the target to a hidden iFrame, which prevent the redirection, but I don't manage to access the result in the body of the iFrame...
What I want: Make an HTTP request similar to the one made by the form. So I tried:
<html>
<head> </head>
<body>
<form enctype="multipart/form-data" norm="form" id="myForm">
Select a file:
<input id="fileInput" type="file" name="upload" accept="image/png, image/jpeg, image/jpg" />
<input type="submit" value="Start upload" />
<label class="button-upload" onclick="send()">Upload</label>
</form>
</body>
<script>
var _file = null;
function send() {
var file = document.getElementById("fileInput").files[0]
console.log(file)
var url = "http://localhost:8080/solve";
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader(
"Content-Type",
"multipart/form-data; boundary=---------------------------169461201884497922237853436"
);
var formData = new FormData();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
formData.append("upload", file);
xhr.send(formData);
}
</script>
</html>
I've checked with the developper tool in network and the request seems to be the same as the one sent by the form, though bottle can't find the file.
The file = request.files.get('upload') returns None and file = request.files returns <bottle.FormsDict object at 0x7ff437abf400> so there's something but I don't understand how to access it!
Any help would be greatly appreciated!
Your JavaScript code seems fine, except for where you set request headers with xhr.setRequestHeader. FormData handles multipart encoding for you, you don't need to set request headers manually. I just tried it, and it seems to be working fine with bottlepy.
Overall, change your send() function as follows:
function send() {
var file = document.getElementById("fileInput").files[0]
console.log(file)
var url = "http://localhost:8080/solve";
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
var formData = new FormData();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
formData.append("upload", file);
xhr.send(formData);
}

Pressing the ajax button again after the first time gives a strange error

Basically when I press the button the first time ajax loads perfectly but when I press that same ajax button again it gives me this error
(index):17 Uncaught DOMException: Failed to execute 'send' on 'XMLHttpRequest': The object's state must be OPENED.
at sendAJAX (http://etc.../:17:5)
at HTMLButtonElement.onclick (http://etc.../:29:40)
I have found articles about this but they are confusing to a point where I don't know how to integrate those solutions to my script, to get it to work with my script so I need a code example solution based on my exact script not based on some one else's script so I can
better understand this based on my script. I mainly want to know how can I keep calling the same ajax request regardless how many times I press that same button with out errors.
Code example
index.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href='//fonts.googleapis.com/css?family=Varela+Round' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/main.css">
<title>AJAX with JavaScript</title>
<script>
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
document.getElementById('ajax').innerHTML = xhr.responseText;
}
};
xhr.open('GET', 'sidebar.html');
function sendAJAX() {
xhr.send();
}
</script>
</head>
<body>
<div class="grid-container centered">
<div class="grid-100">
<div class="contained">
<div class="grid-100">
<div class="heading">
<h1>Bring on the AJAX</h1>
<button id="load" onclick="sendAJAX()">Bring it!</button>
</div>
<ul id="ajax">
</ul>
</div>
</div>
</div>
</div>
</body>
</html>
sidebar.html
<section>
<h2>Welcome to the wonderful world of AJAX</h2>
<p>This content provided to you dynamically by the XMLHTTP Request Object</p>
</section>
You create your xhr element only once, so if sendAJAX is called a second time, then send is called on an XMLHttpRequest that was already send.
After send is called the state of the xhr obeject is not opened anymore and because of that you get the error message.
You can solve the problem by creating new XMLHttpRequest for each sendAJAX call.
function sendAJAX() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
document.getElementById('ajax').innerHTML = xhr.responseText;
}
};
xhr.open('GET', 'sidebar.html');
xhr.send();
}
Or by only moving open into the sendAJAX:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
document.getElementById('ajax').innerHTML = xhr.responseText;
}
};
function sendAJAX() {
xhr.open('GET', 'sidebar.html');
xhr.send();
}
XMLHttpRequest.open()
Note: Calling open for an already active request (one for which open() has already been called) is the equivalent of calling abort().

Phonegapped Android application not working as compared to HTML5 app

I made a HTML5 app, which accessess JSON data from a web service. The app works fine when opened in a browser on desktop computer, but when it is "phonegapped" into Android application it is not working. I have added following line on the PHP server to enable CORS:
header("Access-Control-Allow-Origin: *");
Following is the code:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery.getJSON demo</title>
<style>
img {
height: 100px;
float: left;
}
</style>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>
<div id="images"></div>
<script>
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
}
function onMyClick() {
console.info(new Object("Hello"));
var url = 'http://example.com/mobile/index.php?tag=getAllById&catid=60';
var xhr = createCORSRequest('GET', url);
if (!xhr) {
throw new Error('CORS not supported');
}
xhr.onload = function() {
var responseText = xhr.responseText;
console.info(responseText);
// process the response.
};
xhr.onerror = function() {
console.info('There was an error!');
};
xhr.send();
console.info(new Object("Hello 4"));
}
</script>
<input type="button" value="OK" onclick="onMyClick()"/>
</body>
</html>
Not working as Android app means that I am getting, "There was an error!" message as the above line in onerror event prints, instead of the JSON data as response text, in the console of eclipse. Please could anyone help me get this working as Android application also.
With the above example I can't see what is wrong but there are multiple possibilities.
The domain you are accessing might not be white listed in your config.xml? To allow everything include the following:
<access origin="*" />
See docs about white list for more info here
Another thing which comes to mind, your app needs internet connection to work, do you have the required permissions setup in AndroidManifest.xml?
You need to find the<uses-permission android:name="android.permission.INTERNET" /> declaration.

Categories

Resources