I'm learning JavaScript, and by now I'm stuck in a problem that I'm not understanding. This problem is related with jQuery.get, CORS, jQuery.getJSON and JSONP.
Let's say that I'm writing an html file with some scripts which is accessing to a URL with some JSON content. The html file is in my local file system, and looks like this:
<!DOCTYPE html>
<head>
<title>Test</title>
<script src = "test.js"
charset = "UTF-8"></script>
<script src = "jquery/jquery-1.9.1.js"
charset = "UTF-8"></script>
</head>
<body>
<h1>Test</h1>
<script type="text/javascript">
queryAuctionFiles('eu', 'tyrande');
</script>
</body>
The function queryAuctionFiles, called in the body script tag, is the following:
// File: test.js
function queryAuctionFiles(realm, server)
{
var url = 'http://' +
realm +
'.battle.net/api/wow/auction/data/' +
server;
jQuery.get(url, function(data)
{
alert( "Eureka!" );
});
}
Opening the html with my Chrome browser (V 32.0.1700.76 m) the following error occurs:
XMLHttpRequest cannot load http://eu.battle.net/api/wow/auction/data/tyrande. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
Googling around I was able to learn that this error is due that the resource acquisition from some domain (my local file system) to another (eu.battle.net) is forbidden due to security reasons.
I’ve also read that this cross domain requests could be achieved with CORS, but if I’m not mistaken, this CORS stuff must be enabled in both sides of the petition; in my case: my Chrome must support CORS and eu.battle.net must have it enabled, how can I can find out if some domain supports CORS?
While looking for a solution for my problem, I’ve found about the jQuery.getJSON method, so I’ve gave it a try, but the result was the same, the following code:
jQuery.getJSON(url, function(data)
{
alert( "Eureka!" );
});
Produces the same No 'Access-Control-Allow-Origin' error, at first, I was thinking that the error is produced because the given url isn’t a JSON file, but it is without doubt a cross domain error. When I was thinking about giving up, I’ve read about JSONP and how it is managed by jQuery:
If the URL includes the string "callback=?" (or similar, as defined by the server-side API), the request is treated as JSONP instead.
So, I made the following change:
jQuery.getJSON(url + '?callback=?', function(data)
{ //^~~~~~~~~~~~~
alert( "Eureka!" );
});
And after that, I get a different error:
Uncaught SyntaxError: Unexpected token :
And, the file name where the SyntaxError is marked is tyrande on line 1, the contents of this tyrande file looks like this:
{"files":[{"url":"http://eu.battle.net/auction-data/d5357dc91898b3f78edfd1fbbe8867e8/auctions.json","lastModified":1390475765000}]}
This contents are the input I was expecting in the anonymous function passed as second parameter to getJSON!
It seems that the getJSON has downloaded a file named tyrande, from the url provided, and then eval() its contents, this contents are a JSON input and therefore, isn’t a valid JavaScript evaluable string.
Now that I’ve explained in detail what have I tried, and knowing my goal, lemme ask:
In order to acquire remote resources, it matters if the html file is in my file system or into a remote server?
Is the CORS something that must be enabled? how do I enable it on my scripts? how I must test if a remote resource supports CORS?
If I’m using jQuery.getJSON, it matters if the resource address isn’t a JSON file?
What is that I’m doing wrong in my last change? why is a file named tyrande being downloaded and then its contents being eval()uated?
Thanks for your attention
It is impossible. Cross domain policy won't allow you to fetch a file from different domain.
Check this one out
Related
I have been searching for almost 2 hours to find a way to read a csv file that is hosted online. My data is hosted here.
I came across a library called papa parse. It apparently allows me to do that. I have the following code
Papa.parse("http://bahadorsaket.com/others/ranking.csv", {
download: true,
complete: function(results) {
console.log("Finished:", results.data);
}
})
It returns me following error: *
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'null' is therefore not allowed access.
I was wondering if I am doing something wrong. OR there is a different way to load a csv file that is hosted online.
Thanks
There is chrome extension which can resolve this CORS error
Link :
https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en
Also you can start the chrome with below line which can also resolve it
chrome.exe --disable-web-security
This is for windows btw
Hope this helps
It is not that you are doing anything wrong, its that the remote URL doesnt allow cors and your browser will deny any traffic to remote origins. The safer option would be for you to make that call server side to get the csv and have papa.parse call a local endpoint.
Trying to get my html/JS file to read and print firstName from this link:
http://www.w3schools.com/jquery/demo_ajax_json.js, as trial for something else I want to do.
Received this error: Origin null is not allowed by Access-Control-Allow-Origin, so trying to use crossDomain.
Read this: jquery API but not sure how to implement correctly
My JS code (I know it's off, but no idea how to correct it):
var myArray = [];
var jsonArrayObj;
$.ajax{
crossDomain: true}).done(function(){
$(document).ready(function(){
myArray = $.getJSON("http://www.w3schools.com/jquery/demo_ajax_json.js", function(result){
myArray = JSON.parse(myArray);
console.log(myArray.firstName);
});
});
});
I don't understand what function() does in JS either
You cannot use CORS to access a website unless the website allows you to do so. If CORS was allowed on that endpoint, there would be an HTTP header for Access-Control-Allow-Origin: * (or a specific hostname). So the server you are attempting to talk to has to have a header allowing this to happen.
That endpoint works on the w3schools getJSON() demo page because the JavaScript is running from the same domain as the XHR target (so CORS is not needed).
More here: MDN: HTTP access control (CORS)
JSONP/JSON-P is an alternative to CORS but that endpoint doesn't appear to support it either (at least not with the typical callback querystring key).
Its because of CORS. Try to load file locally.
In your code you are using anonymous function. Internet is full of pages to read about javascript functions.
FUNCTIONS:
http://www.w3schools.com/js/js_functions.asp
https://en.wikibooks.org/wiki/JavaScript/Anonymous_Functions
If you are not familiar with JS syntax try to take online course to get your head around it.
JAVASCRIPT COURSE:
http://www.codecademy.com/en/tracks/javascript
Google for more. ;)
i am trying to download a file from facebook, for example
https://www.facebook.com/download/847027648649013/36654984.doc
using jquery's ajax (not to disk, to js variable...).
since this is for debug purposes i disabled my chrome's 'same origin policy' using -allow-file-access-from-files -disable-web-security
the problem is - im getting 404 while if i put this link in a new browser tab ill get 302 and then a redirect to the actual file.
how would i download this file?
thanks!
You can get the contents of the file using a jquery get function.
The site you are trying to get the file can not container a No Access-Control-Allow-Orign header,
If it does you will recieve the following javascript error:
XMLHttpRequest cannot load https://www.facebook.com/download/847027648649013/36654984.doc". No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://fiddle.jshell.net' is therefore not allowed access.
If you have permission to access the file from another domain or from a file not hosted in the same domain in other words you can you use the following JQuery code:
var url = "https://www.facebook.com/download/847027648649013/36654984.doc";
$.get(url,
function(data){
//store the file contents in the result variable
var result = data;
});
i ended up using a php proxy.
using php's curl solved both sop problem (no need for -disable-web-security) and does the redirect automatically. now i only need to parse the result....
I'm stuck with this for hours now. Please help me to spot the mistake!
Why is this d3.text request failing? (link to diff.php)
d3.text("http://q39.qhor.net/cach/diff.php?action=diff", function(diff) {
document.write(diff); // returns 'null'
});
While this is working? (link to ltcProxy.php)
d3.text("http://freya.syari.net/pool/ltcProxy.php?action=diff", function(diff) {
document.write(diff); // returns a number read from input
});
I've been reading the documentation on this back and forth, tried using different input formats (text/plain, text/html, etc. ...) but I cant get the first snippet to work.
Whats wrong with it?
As you've discovered, if the file request returns with an error, the data object (diff) will be null. You could have figured it out much faster if you always use the two-argument version of the callback function, and make the first line of your function an error check:
d3.text("http://q39.qhor.net/cach/diff.php?action=diff", function(error, diff) {
if (error) {
document.write("Error reading file");
return;
}
document.write(diff); // returns 'null'
});
The "error" object passed in by d3 isn't very useful beyond checking for its existence -- it's the XMLHTTPRequest function that was used, not the error returned. The error itself should be logged to your console by the browser.
Why would a file request return with an error even though you can open the file up directly no problem? Because Javascript is exceedingly polite when using external files: it will only use them if the server includes a header that says they may be used by your webpage.
Specifically, the error message that should be displaying on your console when you try to run that request will be something like
XMLHttpRequest cannot load http://q39.qhor.net/cach/diff.php?action=diff. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://fiddle.jshell.net' is therefore not allowed access.
In other words, you cannot use someone else's file in your script unless it specifically tells your browser that you have permission to use it. The proxy server you use in the second example is fetching the file for you, and then passing it on to the browser with the instruction that it may be used by any website in the http://syari.net domain. If I try to use that file name from JS fiddle, however, I still get an error:
XMLHttpRequest cannot load http://freya.syari.net/pool/ltcProxy.php?action=diff. The 'Access-Control-Allow-Origin' whitelists only 'http://syari.net'. Origin 'http://fiddle.jshell.net' is not in the list, and is therefore not allowed access.
More on Access Control and HTTP requests:
https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
I'm trying to pull in the total shares from a number of pages and have them displayed on my home page. I'm using addthis for the share buttons. I found a way to pull in the required info using JSON here.
Since I have multiple urls I'm storing them in an array, then cycling through and calling each one. Here's my code...
jQuery(document).ready(function(){
var shareCountArray = [ "url1", //Array to put all url's to get share total
"url2"]
shareCountArray.forEach( function(shareUrl) {
var url = "//api-public.addthis.com/url/shares.json?url=http%3A%2F%2F"+ shareUrl +"?callback=?";
jQuery.getJSON(url, function(json) {
alert(json.shares);
});
});
});
It's throwing up the error "Uncaught SyntaxError: Unexpected token : ". I thought this may have been because I included ?callback=? but when I remove that the console throws up errors because they're different origins.
Thanks for your time!
When you include callback=? then jQuery thinks the response is JSONP. JSONP is nothing else than including a JavaScript file. I.e. the response you receive is interpreted as JavaScript. That also means that if the server returns anything else than valid JavaScript, you will get an error. JSON on its own is not valid JS syntax, that's why you get the that error (you can verify that easily by putting {"foo": 42} in the console).
when I remove that the console throws up errors because they're different origins.
JSONP as well as CORS have to be supported by the server. You can't make an Ajax or JSONP request to the server if it doesn't. See Ways to circumvent the same-origin policy for alternatives.
But it actually looks like the service does support JSONP:
When calling services that support html responses, you may omit the .html extension. Optionally, you can use json mode and pass callback=function to specify a jsonp callback wrapper. Content-Type headers are set on responses as appropriate.
Looking at your URL, it is malformed. You should use &callback=? instead of ?callback=?. Multiple request parameters in a URL are separated by &. ? only indicates the beginning of the query string. E.g.
http://example.com/?param1=value1¶m2=value2
Learn more about URLs: https://en.wikipedia.org/wiki/Url