Making a CORS request to Google Static Maps - javascript

I'm trying to make a CORS request to Google's static maps api and return an image to be mounted on canvas (to avoid canvas's Cross Origin protection). I'm not sure if I'm following the instructions correctly (https://developers.google.com/api-client-library/javascript/features/cors) but the xhr request never returns anything.
const position = latLngArg;
var xhr = new XMLHttpRequest();
xhr.open('GET',
`http://maps.googleapis.com/maps/api/staticmap?center=${position.lat()},${position.lng()}&zoom=20&size=20x20&maptype=roadmap&sensor=false&key=AIzaSyBiE2efHKeAptVfVRtj9-ZDeHWPKgNjdNk`)
.then(...)

The XMLHttlRequest open method does not return a promise.
It also does not send the request it only initialize it. In order to set the request you need to call the send method afterwards.
You should register a callback to be triggered upon success by setting the onreadystatechange property.
See an example here.

Native XHR do not work with promises.
You can try the following:
const position = latLngArg;
const xhr = new XMLHttpRequest();
const address = `http://maps.googleapis.com/maps/api/staticmap?center=${position.lat()},${position.lng()}&zoom=20&size=20x20&maptype=roadmap&sensor=false&key=AIzaSyBiE2efHKeAptVfVRtj9-ZDeHWPKgNjdNk`;
xhr.open('GET', address);
xhr.onload = () => onImageReceived(xhr.response);
xhr.send();
function onImageReceived(image) {
console.log(image);
}
You can verify that the xhr.response will be your image, after the request was completed (onload event).
Read more about it here.

Related

How to listen for HTTP call in front end JS

I am working on a site, which uses a 3rd party library to launch a pop up to collect users email addresses.
After the user submits the email address, the 3rd party API is called, following the format https://<API-URL>/collectemail?email=test%40test.com
I want to run a function when that API is called and pass it the email param. How can I listen for that event and then trigger my function?
The best way would be to fork the library and modify it so that, when the API is called, the library code itself calls the code on your site with the email parameter.
If that's not possible, your only other option is to monkeypatch XMLHttpRequest so as to intercept requests, such as with:
// Your code, make sure this runs first:
const origXHR = window.XMLHttpRequest;
window.XMLHttpRequest = function() {
const xhr = new origXHR();
xhr.open = (method, url) => {
origXHR.prototype.open.call(xhr, method, url);
console.log('Connection just opened to:', url);
}
return xhr;
};
// Library code:
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://example.com/?email=test%40test.com');
xhr.send();

JavaScript GET responseText

I'm still learning the basics of JavaScript, and I'm trying to make a simple GET Http Request to return information from an API, but the responseText won't return. Here's the code:
var xhr = new XMLHttpRequest();
xhr.open('GET', "https://api.apithis.net/dictionary.php?define=hi", true);
xhr.send();
console.log(xhr.responseText)
It is because you get response a bit later.
So you need to handle it async. To make this, u need to handle response in callback function, that will be fired at the moment you get response.
I reccomend you to use at least JQuery - it helps at start.
https://api.jquery.com/jquery.get/
if u still whant it using xhr (before xhr.send), i think it can be using:
xhr.onreadystatechange = function () { console.log(this.responseText) }

Is it possible to retry an XMLHttpRequest that I Intercepted?

I am overriding the XMLHttpRequest.prototype.send = function(a,b) { } and XMLHttpRequest.prototype.open = function(a,b) { } so I can intercept every single response I get from every ajax call. Sometimes, some of those requests fail, and when that happens I need to update the cookies for the DOM and retry the failed original XHRs.
Taking in consideration that I have no control over those XHRs, meaning that I don't create them, or execute them, would it be possible for me to retry those XHR with new updated cookies?
Right now, I save the original XHR in a new variable, and when it fails, I do an xhr.open.apply() and then xhr.send.apply(). Using an HTTP Web Proxy like Charles I am able to check my response and I always get error message: Invalid request... I also realized that the difference between the original XHR and the retried XHR is that the X-Request-With header is always missing.
Any ideas on how to solve this issue?
Well, it is possible and I managed to do it.
I created a function to retry the original request, where I pass the same parameters that were passed to the XMLHTTPRequest.prototype.send function that intercepted the XMLHTTPRequest before being send.
function retryOriginalRequest(a,b, args) {
var originalRequest = new XMLHttpRequest();
originalRequest.open(a,b, true);
// The request headers need to be set up after the open call and before the send.
originalRequest.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
originalRequest.send(args, null);
};

How to get only response headers from XMLHttpRequest

Is it possible to get only response headers from XMLHttpRequest without downloading file data?
If the server you are making the request to supports the method, it sounds like what you want is to make an HTTP HEAD request. See the HTTP spec.
For example compare the output from curl -v -X GET https://github.com and curl -v -X HEAD https://github.com.
Also see HTTP HEAD Request in Javascript/Ajax?
Using JavaScript (as specified in the question) simply use a head request via AJAX:
var xhr = new XMLHttpRequest();
var method = 'head';
var url = 'https://www.example.com/';
xhr.open(method,url,true);
xhr.send(null);
xhr.onreadystatechange = function()
{
if (xhr.readyState === 4)
{
console.log(xhr.getAllResponseHeaders())
}
}
Firstly, the answer from John fixes this issue but it got downvoted because it didn't have enough of an explanation.
So here is the fix with an explanation as well as an extra bit that you can add as well.
Client side solution is as follows (I am using the status code as the example):
function checkStatus(url) {
return new Promise((resolve, reject) => {
const request = new XMLHttpRequest();
request.open('HEAD', url, true)
request.onreadystatechange = () => {
if (request.readyState >= 2) {
resolve(request.status)
request.abort()
}
}
request.onerror = (e) => {
reject(e)
}
request.send()
})
}
The reason why this works is for two reasons.
Firstly we are passing HEAD in as the method instead of GET this should be enough on its own, but if you want to do more, you can move onto the second reason.
The second reason this works is because of the readyState states.
0 = UNSENT
1 = OPENED
2 = HEADERS_RECEIVED
3 = LOADING
4 = DONE
At state 2 the headers are ready to be viewed. This means you can then return whatever you need and/or abort the rest of the request preventing any further data being downloaded.
Worth noting you can also do this with request.onprogress at stage 3.
See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState and https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for more details.

XMLHttpRequest receiving no data or just "undefined"

i try to make a Firefox Addon which runs a XMLHttp Request in Javascript. I want to get the data from this request and send it to *.body.innerhtml.
That's my code so far...
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://xx.xxxxx.com", true);
xhr.send();
setTimeout(function() { set_body(xhr.responseHtml); }, 6000);
Instead of receiving the data, I get "undefined". If I change xhr.responseHtml to responseText I get nothing. I don't know why I'm getting nothing. I'm working on Ubuntu 12.04 LTS with Firefox 12.0.
If you need any more details on the script please ask!
Update:
set_body Function
document.body.innerHTML = '';
document.body.innerHTML = body;
document.close();
Update SOLVED:
I had to determine the RequestHeaders (right after xhr.open):
xhr.setRequestHeader("Host", "xxx");
For following Items: Host, Origin and Referer. So it seems there was really a problem with the same origin policy.
But now it works! Thanks to all!
when you set the last param of open to true you are asking for an async event. So you need to add a callback to xhr like so:
xhr.onReadyStateChange = function(){
// define what you want to happen when server returns
}
that is invoked when the server responds. To test this without async set the third param to false. Then send() will block and wait there until the response comes back. Setting an arbitrary timeout of 6 seconds is not the right way to handle this.
This code should work:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
set_body(xhr.responseText);
}
};
xhr.open("GET", "http://xx.xxxxx.com", true);
xhr.send();
Make sure that you are getting a correct response from URL http://xx.xxxxx.com. You may have a problem with cross-domain calls. If you have a page at domain http://first.com and you try to do XMLHttpRequest from domain http://second.com, Firefox will fail silently (there will be no error message, no response, nothing). This is a security measure to prevent XSS (Cross-site scripting).
Anyway, if you do XMLHttpRequest from a chrome:// protocol, it is considered secure and it will work. So make sure you use this code and make the requests from your addon, not from your localhost or something like that.

Categories

Resources