Ajax call using jsonp not working, "Uncaught SyntaxError: Unexpected token" - javascript

Problem
I'm working with a open data, city API for river levels, but when I make my ajax call using jsonp I receive an error for Uncaught SyntaxError: Unexpected token < which doesn't appear to be coming from my scripts.js
It is also my understanding that my ajax call might not be working because this API only spits out XML or json. I've tried to switch my dataType: json, but when I do that I receive the error below. Not particular sure if using jQuery's .getJSON is the best method to grab this data?
Data: http://opengov.brandon.ca/OpenDataService/opendata.html
Documentation: http://opengov.brandon.ca/api.aspx
Error (when switching dataType: json)
XMLHttpRequest cannot load http://opengov.brandon.ca/opendataservice/Default.aspx?date=riverlevel&columns=date&dataset=riverlevel. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
scripts.js
$(function(){
$.ajax({
url: 'http://opengov.brandon.ca/opendataservice/Default.aspx?date=riverlevel&columns=date&dataset=riverlevel',
type: 'GET',
dataType: 'jsonp',
success: function(response){
console.log(response)
}
});
});

You may be interested in reading What are the differences between JSON and JSONP?
A "JSONP response" from a server is actually an executable script. The client runs the executable script, and the script happens to contain the data you want, supplied as an argument to a function. If the server doesn't serve an executable script, that server does not support JSONP.
For your next error, see "No 'Access-Control-Allow-Origin' header is present on the requested resource". Ajax requests to other domains are not permitted, unless explicitly allowed by CORS headers (like the Access-Control-Allow-Origin response header) from the server. Due to the same-origin policy, scripts on one origin are not allowed to access the contents of another origin. Cross-Origin Resource Sharing (CORS) is a way for the server to relax the same-origin policy.
I would suggest contacting the providers of the API and requesting CORS support. In this case, it really is as simple as serving an Access-Control-Allow-Origin: * header in the response. Per the W3C's own security recommendations for CORS:
A resource that is publicly accessible, with no access control checks, can always safely return an Access-Control-Allow-Origin header whose value is "*".
Alternatively, you can set up a reverse proxy server that fetches the API resources for you and serves them on your own origin, as noted in an answer on Ways to circumvent the same-origin policy. Since the same-origin policy is a browser restriction, you can have any server you control fetch the API resource and then serve the response to your browser.

The default data format is XML, but can be changed by setting the format query variable to "json" to return JSON formatted data.
You need to add &format=json to the end of the URL:
http://opengov.brandon.ca/opendataservice/Default.aspx?date=riverlevel&columns=date&dataset=riverlevel&format=json

Related

What is the difference between getJSON() function and post() function when make a request across domain?

I am trying to access a Google Apps Script WebAPI from my website using javascript to pass some value and create an excel file and download it through this API.
I tried 2 following way:
Using POST request with $.post.
My values are many. So, at first, I use a POST request with a body is JSON of list values. Browser rejects API response, because of CORS error.
I researched about CORS to understand it. At some topics, I found a solution is the following second way.
Access to XMLHttpRequest at 'https://script.google.com/macros/s/xxxxxxx' from origin 'https://example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Using GET request with $.getJSON.
I pass JSON of list values to URL parameter and make GET request. It worked fine.
var url = 'https://script.google.com/macros/s/' + api_id + '/exec?' + request_parameter_string;
$.post(url, payload, function(data, textStatus) {
// Do something
}, 'json');
$.getJSON(url, function(json_result) {
// Do something
})
.fail(function() {
// Do something
});
What I do not understand is why? Why it works with getJSON but not work with post?
I think CORS work with both of GET and POST requests. And I checked the response header with Postman. The headers are the same Access-Control-Allow-Origin →*.
I think have something is different inside getJSON and post functions.
*UPDATE: Update POST CORS error message.
GET requests are not bound by CORS we can host images and static files in CDN which is different from the origin and would help in improving the performance by caching and making parallel requests.
Similarly GET is used for serving ads, trackers and analytics from third party domains as well.
More information about Same Origin Policy and GET is at https://security.stackexchange.com/a/16221/9517
How the browsers identify Other HTTP Verbs are allowed for the cross origin request is elaborated # https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request

Need help working with SMMRY API

I'm using http://smmry.com/api for a small project. I'm fairly new to AJAX and have trouble using it. Here's what I have so far:
var a = $.ajax({
type:'POST',
url:'http://api.smmry.com/&SM_API_KEY=XXXXXXXX',
headers: {'Authorization': '["Expect:"]'},
data: {'SM_URL':'https://en.wikipedia.org/wiki/Human%E2%80%93computer_interaction'},
contentType:'application/json',
dataType: 'json',
});
console.log(a);
The error I'm getting:
XMLHttpRequest cannot load http://api.smmry.com/&SM_API_KEY=XXXXXXXX. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
I'm fairly sure it has something to do with headers. I have no idea what to do and would really appreciate it if someone could help me!
The error you are getting has to do with CORS. The XMLHttpRequest sends a preflight request, which is not supported by the SMMRY API, and is something that needs to be enabled server side. What can you do instead?
You can talk to their API through a server, e.g. a simple Node server.
You then send the XMLHttpRequest to your own server, where you do allow preflight request by allowing CORS (this is a simple line of code in a Node / Express server), and you forward the request to the SMMRY API and send the response back to your site. This process is called "proxying".

Javascript CORS blocked but still shows data in packet capture

I have written a web app that is served to the browser from the local filesystem. I am attempting to make an HTTP GET request to another domain using jQuery's ajax method:
$.ajax({
type: 'GET',
url: "http://alerts.weather.gov/cap/us.php?x=0",
dataType: "text",
data: null,
success: function(data){
var x = data;
},
error: function(data, err) {
var x = err;
}
});
In the developer console, I am getting the error, "Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://alerts.weather.gov/cap/us.php?x=0. (Reason: CORS header 'Access-Control-Allow-Origin' missing)."
Now: I understand what this means, and the purpose for this error.
Here's the really weird part: when I take a Wireshark capture of network traffic, I can see that the remote server is, in fact, serving up the content I requested.
Is that the way CORS works? Does it depend entirely on the client receiving data from the server and then refusing to work with it? I haven't found a clear explanation of where CORS is enforced; I expected it to be a server-side error and not a client-side error.
It's frustrating knowing that my browser is getting the data I requested but isn't letting me use it. Are there any workarounds?
CORS depends on the browser and the server. The browser should block the content; the server should respect the OPTIONS verb and return a proper CORS response.

How to consume Json Data in Jquery Ajax

I have a URL, which gives response on browser:
https://api.sandbox.paypal.com/retail/merchant/v1/locations
It gives:
{
"errorCode": 600031,
"message": "Missing access token",
"developerMessage": "You must provide an access token when calling this API. It can be passed as either a header of the form \"Authorization: Bearer \" or as a query parameter called access_token.",
"errorType": "oauth/missing_access_token",
"correlationId": "4de95cd8aa090"
}
I tried this:
$.ajax({
url: "https://api.sandbox.paypal.com/retail/merchant/v1/locations",
dataType: 'json',
type: 'POST',
success: function (data) {
console.log(data);
alert("success", data);
},
error: function (data) {
alert("fail", data);
console.log(data);
alert("Sorry..Please try again later");
},
});
But I am not getting the same response as I am getting on browser. I am getting error.
Please check here
http://jsfiddle.net/ajitksharma/wehGy/
However while debugging on Browser console I got the error:
XMLHttpRequest cannot load https://api.sandbox.paypal.com/retail/merchant/v1/locations. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
You can make AJAX calls to a backend API which is on another domain, however, it needs to return JSONP format and not just JSON, otherwise you get and error. This is due to same origin policy: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy.
This discussion may be helpful to understand JSONP: Can anyone explain what JSONP is, in layman terms?
Since you don't have control over PayPal's API and you can't ask them to return JSONP to you, these requests to PayPal's API need to be done from the server-side script of your application.
Running this from any other location, for example JSFiddle, will give you the Access-Control-Allow-Origin error since you're making a cross-domain request. Please read further about the same-origin policy.
As for the first error, its because your request needs an API key from paypal. See this page about getting an API key and making a simple request.
As Lisa Stoz and kaminari suggested it is not possible to call a service in another domain without some patch work. Now as you see the response when you hit that url via browser it says you need to add an extra header to your ajax request something like 'authorisation'

Origin http://XXXXX.com is not allowed by Access-Control-Allow-Origin

I am trying to make a request to the yahoo wheather forcast like this
function parseXml(woeid)
{
$.ajax({
type: "GET",
url: "http://weather.yahooapis.com/forecastrss?w="+woeid,
dataType: "xml",
success: parse_wheather
});
}
and I get the following error message
XMLHttpRequest cannot load http://weather.yahooapis.com/forecastrss?w=1937103. Origin http://XXXXXXXX.com is not allowed by Access-Control-Allow-Origin.
I know that I can't make the request from localhost , but I am not running a localhost
How can I solve this problem ??
I know that I can't make the request from localhost
Actually, due to the same origin policy restriction you cannot send cross domain AJAX calls. So you are not only limited to localhost. You are limited to anything different than http://weather.yahooapis.com. So unless the page containing your javascript is hosted on this domain you cannot send AJAX requests to it.
Here's a guide you might take a look at about cross domain AJAX calls. In your case you could use a server side bridge. So you will define a server side script on your domain that will fetch the remote domain results and then you could send the AJAX request to your script in order to avoid violating the same origin policy restriction.

Categories