Requesting Google Place API with xhr got CORS issue - javascript

On my webpage I have some javascript code to query Google Place API (GET) for response. Here's my code look like:
// Sending XHR request
var url = 'https://maps.googleapis.com/maps/api/place/textsearch/json?query=KPMG+Seattle&key=<<MY_KEY>>';
var xhr = createCORSRequest('GET', url);
xhr.setRequestHeader('Access-Control-Allow-Headers', '*');
xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
xhr.send();
//**********************//
// Create the XHR object.
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;
}
I am running this local HTML file in my browser, and got CORS error:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'null' is therefore not allowed access. The response had HTTP status code 405.
I am wondering what the problem can be (I added Access-Control-Allow-Origin to request header)? According to the Google Tutorial this should be enough to make a request?
Please help point out where I am doing wrong... Thanks!

Please see this post XMLHttpRequest Origin null is not allowed
Basically there is a security feature you need to disable to allow XHR of different origin if you are running from a local file.
See the first answer in the post.

Related

Get source code for a specific page using JavaScript

The code below displays the source code of the current page:
Website as example: http://jsfiddle.net/635YY/1/
var url="../635YY",xmlhttp;//Remember, same domain
if("XMLHttpRequest" in window)xmlhttp=new XMLHttpRequest();
if("ActiveXObject" in window)xmlhttp=new ActiveXObject("Msxml2.XMLHTTP");
xmlhttp.open('GET',url,true);
xmlhttp.onreadystatechange=function()
{
if(xmlhttp.readyState==4)alert(xmlhttp.responseText);
};
xmlhttp.send(null);
How to display the source code of another page (other than the current page)?
url="/about";
var xhr = new XMLHttpRequest();
xhr.onload = function() {
alert( this.responseXML.documentElement.innerHTML );
}
xhr.open( 'GET', url );
xhr.responseType = 'document';
xhr.send();
Unfortunately you will not be able to do this with pages on another website unless the CORS policy on the website allows it, or you will get an error like
Access to XMLHttpRequest at 'https://test.com/' from origin 'http://jsfiddle.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

How to set CORS header in an AJAX call with pure JavaScript that is hitting other rest service?

I am having following JS function that gets called on html page load. When the page loads I see following error in the Firefox console logs.
Firefox Console Log:
"NetworkError: 403 Forbidden - http://localhost:8080/publicKey/lookup/TRUUS2"
TRUUS2
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/publicKey/lookup/TRUUS2. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
publickey.js
function loadPublicKey() {
var xmlhttp = createCORSRequest('GET', 'http://localhost:8080/publicKey/lookup/TRUUS2');
xmlhttp.send();
xmlhttp.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
alert(this.responseText);
document.getElementById("keyDiv").innerHTML = this.responseText;
}
};
}
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Check if the XMLHttpRequest object has a "withCredentials" property.
// "withCredentials" only exists on XMLHTTPRequest2 objects.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// Otherwise, check if XDomainRequest.
// XDomainRequest only exists in IE, and is IE's way of making CORS requests.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// Otherwise, CORS is not supported by the browser.
xhr = null;
}
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
return xhr;
}
I have already added xhr.setRequestHeader("Access-Control-Allow-Origin", "*") statement to fix the CORS issue but no luck. I am looking for pure JS implementation.
Note: I am able to hit the http://localhost:8080/publicKey/lookup/TRUUS2 URL successfully through Postman and getting the response as well. No issues there.
Not sure what am I missing. Please guide.
Based on the input provided by Rory, I removed the xhr.setRequestHeader("Access-Control-Allow-Origin", "*") from the JS and added snippet #CrossOrigin(origins = "http://localhost:8084") in my controller and that solved the problem.
#CrossOrigin(origins = "http://localhost:8084")
#RestController
public class PublicKeyLookupController {
//code removed for brevity
}

Setting CORS call to GET not OPTIONS

I am creating a CORS call as follows:
createCORSRequest: function(method, url) {
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
if ("withCredentials" in xhr) {
// Check if the XMLHttpRequest object has a "withCredentials" property.
// "withCredentials" only exists on XMLHTTPRequest2 objects.
console.log("Sending request with credneitials");
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// Otherwise, check if XDomainRequest.
// XDomainRequest only exists in IE, and is IE's way of making CORS requests.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
xhr.setRequestHeader('Authorization', 'Bearer bf6dcfd4e975a007dc8184be6bcf580c'); //Authorization details needed
return xhr;
}
The problem is that this is always sent as an OPTIONS call, which the server does not handle at all. If I remove
xhr.setRequestHeader('Authorization', 'Bearer bf6dcfd4e975a007dc8184be6bcf580c');
then it becomes a GET request but the server will not process it without the access token.
Is there a way to send the Authorization Header in the GET request ?
Or will I have to modify the server to handle OPTIONS requests ? I.e. preflights and so forth.
Thanks for the help.
If you set an Authorization header then you are making a complex request and you have to handle the OPTIONS preflight before the browser will make the GET request.
You can't set the header without handling the OPTIONS request.

How to get some page by url in javascript

I want to get page from web-site using javascript.
I have url like:
http://not-my-site.com/random
From 'random' I will be redirected to another (random) page on the web-site.
Postman do everything like I want :) It's get whole page (html). But how can I do the same from javascript?
I tried CORS alredy following this guide http://www.html5rocks.com/en/tutorials/cors/ but without success. I still just get an error:
XMLHttpRequest cannot load http://not-my-site.com/random.
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
Code from tutorial:
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// Check if the XMLHttpRequest object has a "withCredentials" property.
// "withCredentials" only exists on XMLHTTPRequest2 objects.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// Otherwise, check if XDomainRequest.
// XDomainRequest only exists in IE, and is IE's way of making CORS requests.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// Otherwise, CORS is not supported by the browser.
xhr = null;
}
return xhr;
}
var xhr = createCORSRequest('GET', 'http://not-my-site.com/random');
if (!xhr) {
throw new Error('CORS not supported');
}
xhr.onload = function() {
var responseText = xhr.responseText;
console.log(responseText);
// process the response.
};
xhr.onerror = function() {
console.log('There was an error!');
};
xhr.send();
And also I tried common xhr like this (got the same error):
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://not-my-site.com/random', true);
xhr.send();
This seems to be a problem of CORS not being configured correctly on the server. The below PHP code should allow any request from any domain. (If you're not using PHP, it should be easy to convert the below code into any other language, the clue is to write to the HTTP header).
Remember to place this code before any HTML is outputted.
$origin=isset($_SERVER['HTTP_ORIGIN'])?$_SERVER['HTTP_ORIGIN']:$_SERVER['HTTP_HOST'];
header('Access-Control-Allow-Origin: '.$origin);
header('Access-Control-Allow-Methods: POST, OPTIONS, GET, PUT');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Headers: Authorization, X-Requested-With');
header('P3P: CP="NON DSP LAW CUR ADM DEV TAI PSA PSD HIS OUR DEL IND UNI PUR COM NAV INT DEM CNT STA POL HEA PRE LOC IVD SAM IVA OTC"');
header('Access-Control-Max-Age: 1');
Accepting requests from all domains is insecure. For a better (but slightly more complex) solution, see here: CORS That Works In IE, Firefox, Chrome And Safari

Does bitly API support CORS?

I saw in their documentation that CORS is supported. But my attempts to make request from JavaScript have no success.
Requesting this URL:
https://api-ssl.bitly.com/v3/shorten?longUrl=https://google.com/&access_token=token&domain=bit.ly&format=json&languageCode=en-US
I receive standard error :
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://google.com' is therefore not allowed access.
UPD: bitly documentation - http://dev.bitly.com/cors.html
If anyone still having this issue. The reason this happen is because the option (preflight) response from bitly doesn't include 'Access-Control-Allow-Origin' header.
to get around this I used XMLHttpRequest which doesn't send preflight.
let xhr = new XMLHttpRequest();
let url = 'https://api-ssl.bitly.com/v3/shorten?longUrl=https://google.com/&access_token=token'
xhr.open('GET', url);
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
if(xhr.status===200) {
console.log(xhr.responseText)
} else {
console.log(xhr)
}
}
};
xhr.send();
It is actually mentioned in bitlly's documentation

Categories

Resources