Accessing specific API - javascript

So I am trying to access an OpenFEMA API for funding data, but I am pretty new to APIs and I am trying to access the API using Javascript. I ran into the Same-Origin Problem and started using CORS.
So my code currently looks like this:
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);
console.log('1');
} 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);
console.log('2');
} else {
// Otherwise, CORS is not supported by the browser.
xhr = null;
console.log('3');
}
return xhr;
}
var xhr = createCORSRequest('GET', "http://www.fema.gov/api/open/v1/PublicAssistanceFundedProjectsDetails");
alert(xhr.responseText);
but the alert box is empty when it comes up. I am really not sure what I am doing wrong. would love some help.

The function you are using only creates the request; it doesn't send it or wait for results. You would still need to set up an onReadyStateChange handler, then call xhr.send(), to see the results.
More importantly, though, the API you are accessing does not permit cross-origin requests. It cannot be accessed from off-site through Javascript.

Related

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.

Requesting Google Place API with xhr got CORS issue

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.

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

facebook graph api ajax XMLHttpRequest - Null result?

Summary: Keep getting null response despite public data and setting callback to enable cross domain JSON. Please help!
A similar question has been answered here
Using the new facebook graph api, ajax calls returns null (empty)
but I'm not using jquery and have tried to adapt my code to reflect that answer.
I'm trying to use a simple example to test a simple xmlhttprequest handler. I have this link in my page:
<a href='javascript:loadXMLDoc(\"https://graph.facebook.com/btaylor?callback=methodname\",\"\")'>AJAX LINK</a>
The callback=methodname parameter is to enable cross domain JSON
I'm using a generic XMLhttprequest builder:
var req; // Request object
function loadXMLDoc(url,params){
// branch for native XMLHttpRequest object
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.setRequestHeader("Content-length", params.length);
req.setRequestHeader("Connection", "close");
req.send(params);
// branch for IE/Windows ActiveX version
} else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
req.setRequestHeader("Content-length", params.length);
req.setRequestHeader("Connection", "close");
req.send(params);
}
}
}
I then have a handler :
function processReqChange(){
if (req.readyState == 4) {
if (req.status == 200) {
alert("Done");
} else {
//alert("There was a problem retrieving the data:\n" + req.statusText);
alert("Status Code = "+req.status);
alert("There was a problem retrieving the data:\n");
alert("Failed : object = "+req);
alert(req.responseXML);
alert("Failed : response = "+req.responseText);
alert("Failed : status = "+req.statusText);
}
}else{
}
}
But I keep getting a null response (statusText OK, status code 0). Any ideas?
Thanks in advance
You can't make a cross-domain ajax request. Look into whether or not they support JSONP, or use the FB.api method from their javascript SDK
http://developers.facebook.com/docs/reference/javascript/FB.api
EDIT: I didn't read your post very thoroughly when I replied.
I see that you're adding the callback name to your ajax request, which isn't going to do any good because you're still making an XHR request, so it will still fail cross-domain. You seem to be misunderstanding how JSONP works.
Normally I'd just suggest using a framework like jQuery to abstract out the work that you shouldn't have to reinvent. If you're absolutely dedicated to doing this without jQuery, start by reading the wikipedia article on how JSONP works:
http://en.wikipedia.org/wiki/JSON#JSONP
The basic idea is:
Create a script node where the src attribute looks just like the URL you're trying to request now.
The server will respond with something like : methodname({"foo": "bar"}); instead of just JSON. Since this is being requested via a script node, your browser will execute the "methodname" function and pass in the results.
implement methodname(response) function to handle the response (i.e. do the work you intended to do in processReqChange)
Remove this line and try again:
req.setRequestHeader("Connection", "close");
It sets up the connection to close automatically, often before the send is complete.

Categories

Resources