I am trying to get the contents of http://en.wikipedia.org through an ajax call. For this, I am using jQuery. Here is the code:
jQuery.ajax({
url:"http://en.wikipedia.org",
crossDomain: true,
dataType: "jsonp",
jsonpCallback: "myCallback"
});
function myCallBack(data){
console.log("ok");
}
The problem is that I get in Firebug this error:
SyntaxError: syntax error
<!DOCTYPE html>
So I would say that the html content is fetched, although the callback function is not run. At some point it encounters the specified tag, throws this error and stops running the script.
Do you have any idea where the problem might lie?
Is there any other way to get the contents of a html page? I do not want to use iframes, because that means I will not be able to use or modify its contents.
Its because you're Ajax function expects a json response from the provided url and it gives an html response, thats the reason you are getting a syntax error, the same error you will get from the Chrome debugger as well.
Updated:
What you're trying to do is called a Cross-Domain Request.
"For security reasons scripts aren't able to access content from other domains. Mozilla has a long article about HTTP access control, but the bottom line is that without the website themselves adding support for cross-domain requests, you're screwed."
Reference
Solution:
You can resolve this issue by having a backend script which will the external pages for you. Like a proxy server, which resides the same domain, so you wont have to face the Cross domain issues.
And you can load them, by
$.get(url, success: function(data) { // the url that will fetch the external html page for you, located on the same domain
console.log("ok");
});
Your issue your having here is that you are calling across domains. Allthough you seem to have realised this and are using jsonp for your request, the document you are trying to pull ie wikepedia is not a jsonp document. So as soon as the ajax finds the html tags it will throw an arror, as you have defined that you are expecting a jsonp response.
You cannot just pull other websites data across domain with javascript due to the cross domain issues, if you want to accomplish what you are doing here you will need to use a back end language to get the data.
Usefull link is http://json-p.org/
Hope that helps
Related
I have already published a app script, and I test the query string in the browser, and it works well. I would like to send a xmlhttprequest to the script, but it shows =>
XMLHttpRequest cannot load https://script.google.com/macros /s/XXXXXXXXXX/exec. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://docs.google.com' is therefore not allowed access.
This is the app script code:
function doGet(e){
Logger.log(e.parameter.id);
//other function
return ContentService.createTextOutput("Hello World");
}
Here is the client code:
$.ajax({
url:'https://script.google.com/macros/s/XXXXXXXX/exec',
method:'POST',
data:{
id: "123123"
},
success:function(){
console.log("success");
}
});
There are a few possibilites, and I have ran into this error before myself. As I have insufficient reputation to comment and ask for clarification, I will write the most probable cause.
This problem has 2 parts - You can't post (unstringified) objects, and errors on google apps script do not have CORS headers
solution: stringify and parse the object
Without converting the object to a string, your browser will just send [Object object] and not the information.
This will cause an error on your script, and error messages by Google Script are HTML webpages that don't have CORS headers, which triggers the CORS error that does not really tell you the true problem
To be able to successfully POST the parameters, you have to convert the object to a string (e.g. by using JSON.stringify()), get the value through e.postData.contents on your google apps script, parse it, before you can use it as if it were an object.
I personally found when I read that I can't send raw objects in javascript - pass object via post
You mentioned that the code worked when you tested it using the query string in your browser, however, it is different as that will be a GET request and will trigger doGet instead of doPost
this is the most probable explanation and hope it helps!
Do test your code with default values before deploying it as once you deploy your code it can get very troublesome. You can use https://hurl.it to see what actually comes out without cors errors in the way.
I am really getting confused. If I post into a browser the following link, it works, no problem, but when I ask jQuery do to it, it comes back blank, but no error.
Link:
http://www.theyworkforyou.com/api/getConstituency?key=FU8MWTEQnvVsHC6GM7B82zie&postcode=BS345NT
Code:
$.ajax({
url: 'http://www.theyworkforyou.com/api/getConstituency?key=FU8MWTEQnvVsHC6GM7B82zie&postcode='+postcode+'&output=js',
type: 'POST',
success: function(response) {
console.log(response);
}
});
I can change the Key, so don't worry about the fact I posted it.
Any ideas why it's not working?
Your javascript is running in the context of a web page downloaded from an origin server into a browser. It tries to request a page from a different server, but this is a violation of the same origin policy. Javascript cannot make requests to servers other than the origin server.
The JSONP technique can be used to get around this, but only if the non-origin server supports it. In this technique the javascript code dynamically creates a script tag whose src element 1) points to the non-origin server, and 2) passes (as a query parameter) the name of a function which exists in the local javascript. The non-origin server returns the source code of a script which merely invokes the function on data provided by the non-origin server. In this way the javascript can request data from a non-origin server.
If the non-origin server does not support JSONP, then you won't be able to do what you want.
I'm working on an application which use ajax call to get html from the server.
When I run it on the server, everything works fine.
But when I'm running on a localhost, I've a 'Access-Control-Allow-Origin' error.
I looked arround and it seems like using jsonp could be the solution.
So, my ajax call looks like that:
$.ajax({
url: url,
dataType: 'jsonp',
crossDomain: true,
type: 'GET',
success: function(data){
// should put the data in a div
},
error: function(){
//do some stuff with errors
}
});
I get html from the server, but I always have this error:
Uncaught SyntaxError: Unexpected token <
Is there a way to wrap the jsonp response in html?
Thanks!
You can't use JSONP to grab an HTML document. You need to wrap your HTML in a JavaScript variable. JSONP has some very specific requirements to make it work properly, including a callback function/attribute. If you're not in control of the server hosting the target page, you won't be able to make it work. This is a security precaution to prevent a random page from being able to steal your personal information from sites you're logged into via an AJAX call.
UPDATE
I read your question more thoroughly. It sounds like your problem is that you're in a development environment that doesn't have the resource in question. JSONP isn't the answer because it's a lot of trouble to get running just to make your page work in development. You should create a local copy of the target HTML and grab it using a relative or server-absolute URL such as "/the/page/i/need.html" instead of "http://myserver.com/the/page/i/need.html"
If you want to get the data by jsonp, then the server side need to support jsonp.
There is no way just change the dataType to get the data.
If the server side doesn't support jsonp, then you need to make a proxy in your localhost.
As the title says I'm attempting to retrieve a json from an api given by the site. I've tried a variety of things now and have gotten varied results. I want to be able to retrieve and parse the json to get the information that I want out of it. Here's what I've tried:
1) $.ajax()
Code chunk (runs when a button is clicked):
$.ajax({
type: 'GET',
url: url,
dataType: 'json',
success: function(data) {
alert('Success!');
}
});
This produces a "Origin null is not allowed by Access-Control-Allow-Origin." error and does not get a response from the server (for Chrome or FF, I don't care about IE since this is a small project for my use). Looking around I thought the problem might be that I need it to be a jsonp dataType since I am trying to connect to an outside website. This lead me to try #2
2) $.ajax with jsonp dataType
$.ajax({
type: 'GET',
url: url,
dataType: 'jsonp',
success: function(data) {
alert('Success!');
}
});
I also appended "&callback=?" to the end of "url" that I give to the function. Using Chrom's Dev Tool I can see a response from the server this time but the alert never displays. I used JSONLINT to confirm that the response was a proper json (it is) and I've tried setting the json to a variable so I can play with it (along the lines of initializing a variable earlier in the script tag [var response;] and trying to assign the json to it[response = data;]). This produced undefined when I tried to alert(response); later on (I don't believe the response=json; bit ever got called for some reason).
I've also tried using $.getJSON but looking at the api for it it apparently just runs $.ajax anyway (I luckily got the same responses/errors when trying json vs jsonp for $.getJSON as I did when trying $.ajax). When I try as a jsonp Chrome (FF doesn't produce this error) shows a "Unexpected Syntax Error: Unexpected token :". This makes me think that the site I'm trying to talk to doesn't have jsonp working and I can't access the third party site as just a json request. The link talks about how setting the server to return as application/json rather than text/html, like I get from my response, fixed the problem for them (but again, I'm trying to access a third party site and thus I can't access the server).
I've tried this in Chrome and FF and looked at Dev Tools/Firebug for each and seen the same thing (though FF doesn't produce the origin error, but that's apparently a bug with Chrome anyway).
Also: I've taken the json response returned and run $.parseJSON on it and been able to grab various pieces but how can I access the json once I get $.ajax/$.getJSON working?
Any thoughts/solutions would be greatly appreciated.
I once got the Unexpected Syntax Error: Unexpected token : error too.
It seems like the site doesn't support Cross-Domain-Loading.
What API are you trying to use?
More than likely the response is valid JSON, but not valid JSONP. The 3rd party server has to support JSONP for you to get a JSONP response. If you do not have control of the 3rd party server, your only real option is to use a server-side proxy or YQL.
Don't use JQuery AJAX for JSONP.
Use <script type='text/javascript' src=' URL_GOES_HERE&callback=BLAH '></script> which will surround the json object with a javascript method call, and you can then use the data from the 3rd party source.
http://en.wikipedia.org/wiki/JSONP
Try the JSONP plugin. It's one of the few plugins I recommend, only because it's light and does what it should. It also allows you to check for responses other than success. Works great for JSONP, and resolved an issue I had with using a subdomain and not getting proper error responses (which subsequently just halted the code).
Get it Here.
Did you tried this way ?
$.getJSON( url + "?callback=?", function(data) {
console.info(JSON.stringify(data, null, 2));
});
This is basically how I'm managing my JSONP callback to http://freegeoip.net/json/
Here is the error message:
XMLHttpRequest cannot load (the url1). Origin http://localhost:8081 is not allowed by Access-Control-Allow-Origin.
Here is the code:
$.ajax({
url: (the url2),
async : false,
data: { fbId : eh,
fbSecret : meh,
key : bleh
},
datatype: "json",
success: function(result){
console.log(result);
}
});
I know the url is correct because when I click it it gives me the data I need, which is like {"names" : ["blah"]}
Do I need to give out any more details?
I've tried various things like using jsonp/html instead of json, putting data directly into the url instead of separately as data, and using $.get instead of $.ajax, along with editing $.ajaxsetup....
the error message says it all, you cannot make cross domain ajax requests (exception in case of jsonp but that also has to be supported by the server) due to same-origin-policy
this may help you here http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-cross-domain-ajax-request-with-yql-and-jquery/
ports mismatch ;) the page that tries to establish the request has to be on the same port ;)
I think you are trying to access a server different than the one you served the script from - the JavaScript code inside a page served from server A can access only server A using XmlHttpRequest.
If this is the problem there is no easy solution - you have to use proxy or avoid XmlHttpRequest altogether.
same-origin-policy is a browser security measure that restricts JavaScript code from talking with resources originating from other websites i.e resources loaded from any other domain and/or port. eg. JS running in a web page on http://google.com:80 cannot interact with data loaded from http://cbs.com or even http://cbs.com:8081
Working around SOP
a) Proxy in your server: you create a end point in your app that talks to the external url and returns the result
b) Load the JSON response into a <script> tag otherwise jsonp i.e json with padding
eg:
var url = "http://localhost:8081/?queryString=asdsa&callback=jsonCallback";
var script = document.createElement("script");
script.setAttribute("src", url);
script.setAttribute("type", "text/javascript");
window.jsonCallback = function(jsonObj) {
// use JSON object here
// cleanup
document.body.removeChild(script);
delete window[callback];
}
document.body.appendChild(script)
In your case since you are running it of a different port it is not valid and hence the error thrown by the browser..
and there are some server side changes that go along with this.. read up on how to do it for your scripting language..
basically the response should be something like:
jsonCallback({"Name": "Random", "Id" : 2432, "Rank": 453})
Use dataType: "JSONP" to overcome the limitation you encountered; check out the documentation to implement it correctly. You also have to provide a callback function for it.