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.
Related
I'm trying to call the Binance API to get the LTC price in BTC and I tested the link on my browser "https://api.binance.com/api/v1/ticker/price?symbol=LTCBTC" How do i get the json file from that link into my javascript file?
$(document).ready(function() {
var url = 'https://api.binance.com/api/v1/ticker/price?symbol=LTCBTC';
$.ajax( {
url: url,
dataType: 'jsonp',
type: 'GET',
success: function(data) {
console.log(data); //returns nothing
}
});
})
As mentioned in other answer, there is CORS issue. So you can try with proxyURL from client side as below,
$(document).ready(function() {
var url = 'https://api.binance.com/api/v1/ticker/price?symbol=LTCBTC';
const proxyURL = "https://cors-anywhere.herokuapp.com/";
$.getJSON(proxyURL + url, function(playerData) {
console.log(playerData);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Hope it helps.
The request to https://api.binance.com/api/v1/ticker/price?symbol=LTCBTC provides json data this uses CORS policy
{"symbol":"LTCBTC","price":"0.01520100"}
JSONP would look like
myCallback({"symbol":"LTCBTC","price":"0.01520100"})
This looks like and works like a Javascript / PHP function.
The URL for a jsonp includes a callback in the URL ... https://api.binance.com/api/v1/ticker/price?symbol=LTCBTC&callback=myCallback
But is not supported on this site
{"code":-1101,"msg":"Too many parameters; expected '1' and received
'2'."}
It might be openable with php on your site? I can not test from the system I'm on I don't have socket transport "ssl" setup on my tablet to test.
Yes it works from a PHP wrapper.
myJSONP(<?php echo file_get_contents('https://api.binance.com/api/v1/ticker/price?symbol=LTCBTC');?>);
If you check on console after change dataType: 'jsonp' to dataType: 'json', you will get the following as your code and their script not on same host and they need to enable Access-Control-Allow-Origin to access from other domain. You may use cur if you use php.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://api.binance.com/api/v1/ticker/price?symbol=LTCBTC. (Reason: CORS header 'Access-Control-Allow-Origin' missing).
While performing the request from your browser or postman or fiddler you will get the result
But while performing a request from the application you will be failed with error message
Access to XMLHttpRequest at 'https://api.binance.com/api/v1/ticker/price?symbol=LTCBTC' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
The issue has to be fixed from your server side end.
Please refer
Cors understanding
Also, find the solution to the problem if you're using C# .Net as your backend
Solution for cors
AJAX call:
$.ajax({
url: "http://myserver2:296/api/Demo/HelloWorld",
type: "GET",
dataType: 'JSONP',
jsonp: "callback",
headers: { 'API_KEY': 'mykey09090' },
success: function (result) {
console.log(result);
},
error: ajaxFailed
});
function ajaxFailed(xmlRequest) {
alert(xmlRequest.status + ' \n\r ' +
xmlRequest.statusText + '\n\r' +
xmlRequest.responseText);
}
I get the following error: Failed to load resource: the server responded with a status of 403 (Forbidden). However when I use Postman, I just have to add the headers with the http://myserver2:296/api/Demo/HelloWorld url it returns the string.
Can I please get some assistance to resolve the issue.
My goal, is to allow the origin server along with the API key correctly provided to get the data back from the Web Api.
Adding the API_KEY header to the request triggers your browser to first send a CORS preflight OPTIONS request. Any headers you add to a request other than headers defined as CORS-safelisted request-headers will trigger your browser to send a CORS preflight OPTIONS request.
I can’t tell for sure but it seems like the 403 you’re seeing is from your server responding to that OPTIONS request, and saying it doesn’t expect to get OPTIONS requests and doesn’t allow them.
The reason you don’t get this from Postman is that unlike browser engines, Postman does not implement CORS, so it does not send the OPTIONS request. (Postman does not operate under the same-origin Web-security model that browsers enforce for Web applications.)
So to make your client app work as expected for scripted cross-origin access to that server, you must configure the server to respond in the right way to that CORS preflight OPTIONS request.
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".
I have been working on a personal webapp and have hit a little snag. My API calls only work for some APIs and not for others. For the ones it doesn't work with I will usually get an error message like so.
XMLHttpRequest cannot load https://api.meetup.com/2/cities. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
After doing some research I know it is to do with CORS not being setup. I was wondering if it would be possible to set this up in the client when making an AJAX request. The current way I am doing this is like so
var handleRequest = function(request){
$.ajax({
type: "GET",
url: request,
success: function(data) {
var rawJSON = JSON.stringify(data, null, 2);
editor.setValue(rawJSON);
},
dataType: 'json'
});
The server you're trying to access has to grant you permission to access it. An IT admin has to provide you with a URL that grants you permission to hit their external server. The server you are trying to hit has to setup CORS. http://enable-cors.org/
According to their docs they support JSONP.
https://www.meetup.com/meetup_api/
This is your way around CORS.
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