Can't make get request using ajax - javascript

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.

Related

Scrape info from external XML url with jQuery

I need to scrape/parse some info from an external XML file (xml hosted on other domain) and place that info on my site.
I tried this, and didn't succeed:
jQuery(document).ready(function()
{
jQuery.ajax({
type: 'GET',
url: 'http://42netmedia.com/smart/signal_onAir10.xml',
crossDomain: true,
dataType: 'jsonp',
success: parseXml
});
});
function parseXml(xml)
{
jQuery(xml).find('nowOnAirTitle').each(function()
{
jQuery(".my-site-element").append(jQuery(this).find('nowOnAirTitle').text());
});
}
I hope I managed to explain properly.
PS. I am using jQuery because my site is hosted on WordPress
The short answer is that you cannot do what you're trying to do from Javascript running in a browser.
The same origin policy will block AJAX requests for URLs on different domains. There are a couple of exceptions to this policy:
If the target server supports CORS, it can indicate that cross-origin requests are OK. The URL you are trying to reach is on a server that does not support CORS.
If the target server supports JSONP, your script can retrieve data from the target server by using a <script> tag in your page with a src attribute pointing to the target URL and including a callback parameter to tell the server to wrap the data in a javascript function that returns the data. The URL you are trying to reach is on a server that does not support JSONP.
Yes, jQuery does allow you to make a JSONP request across to the other domain, but the response is not Javascript but XML. Your browser is trying to execute the XML as if it was Javascript and fails with a syntax error.
Any solution to this will require server-side support on the server which hosts your code. You could set up a proxy URL on your web server, but you'd need to do that very carefully because you don't want your server to be used as an open proxy. You could also use a cron job to grab the URL using curl and save it to a static file on your server, but that's probably a bit rude.

Simple example to retrieve jsonP data from website

I've seen many examples for JSONP but I can't seem to get any to work for my website. It can generate a JSON code at some url but I can't retrieve it from a different domain. Can you please give me a working example of JSONP that can retrieve data from any JSON file (eg. www.w3schools.com/json/myTutorials.txt).
I may not fully understand, but I just need an explanation, at least, of why if I replace a url with the example above, no data is being pulled.
This is a modified version of the example in the jquery docs using Yahoos public APIs.
$.ajax({
url: "https://query.yahooapis.com/v1/public/yql",
// Tell jQuery we're expecting JSONP
dataType: "jsonp",
// Tell YQL what we want and that we want JSON
data: {
q: "show tables",
format: "json"
},
// Work with the response
success: function( response ) {
console.log( response ); // server response
}
});
Along with a jsbin: https://jsbin.com/tuketa/edit?js,output
The reason for the existence of JSONP is to get around the limitations of CORS rules. For security reasons your browser, in general, is only allowed to communicate to the server it loaded the page from. JSONP was created to get around this by giving the server a callback function with which to pad the JSON data, hence the P in JSONP.
As noted in the comments by jasonscript, it's not any server that can function with JSONP, it has to be configured be able to work with JSONP such as the Yahoo API in the example.
There's many answers out there pointing out the difference between JSON and JSONP. Your question ("...jsonP that can retrieve...") shows that you didn't fully understand the concept. JSONP is a format of answer, as is HTML, XML, JSON. And so the server that responds the request should be able to send it JSONP formatted.
from a different domain... from any json file... it's not possible. The server response it's actually a javascript that wraps a json object.
jsonP is a protocol. the requester (the javascript in the browser) can't request via XHR (ajax) outside the source server:port due the Same-Origin-Policy (SOP).
To bypass the SOP, JSONP born.
The client does not send a XHR request, instead adds a <script> tag to the DOM, with the src attribute pointing to the URL of the jsonP with a parameter (e.g. callback=foo) which tells the name of the local function who receives the JSON as parameter.
Then, the remote server -who understands JSONP- sends a javascript who calls the local function with the JSON as parameter.
Like this example:
Client javascript code:
function foo(data)
{
// do stuff with JSON
}
var script = document.createElement('script');
script.src = '//example.com/path/to/jsonp?callback=foo'
document.getElementsByTagName('head')[0].appendChild(script);
(taken from here)
Server Response:
HTTP/1.1 200 OK
Content-Type: text/javascript
foo({ "key" : "value" });
So, the browser loads the script, calls foo with the json as parameter. Now, You have bypassed the SOP restrictions.

consuming PHP service returning valid json with $.ajax

I've been stuck on consuming a web service created in PHP, not sure what I'm doing wrong.. Ive created a fiddle example here : http://jsfiddle.net/e97AV/
I've tried various combinations of things but keep on getting 404 not found feedback, when I specify jsonp i get no error message, but in the web console i can see a 404 error.. in the browser when I visit the url it is returning valid json
My question is how would I know when to use jsonp or json? Also these service have been provided to me from an external source other than agreeing on json being returned how would I know if the problem is on my side or theirs?
heres the ajax code
baseUrl = "http://exclusivegetaways.co.za/api.php";
$.ajax({
type: "GET",
url: baseUrl,
data: {something : "something"},
//contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
alert("works");
alert(result);
},
error: function (a,b,cc) {
alert(a+b+cc);
}
});
I've since been able to pull json data from the ajax error object?? like so:
baseUrl = "http://exclusivegetaways.co.za/api.php?something=something";
$.ajax({
type: "GET",
url: baseUrl,
dataType: "json",
success: function (res) {
alert("worked");
//alert(res);
},
error: function(jqxhr) {
try {
f = JSON.parse(jqxhr.responseText);
...valid json returned here
} catch(err) {alert(err);}
}
});
This is because of a security restriction that prevents Ajax from querying remote locations.
As a workaround to enable access to a remote location via Ajax, you could build a custom URL in your webApp (in PHP for instance) which queries the distant API and returns JSON.
Then, in your JavaScript, you call this URL (from your application) via Ajax.
First: Always look at your JavaScript error console.
XMLHttpRequest cannot load http://exclusivegetaways.co.za/api.php?location=provinces.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://fiddle.jshell.net' is therefore not allowed access.
See also Ways to circumvent the same-origin policy
I've tried various combinations of things but keep on getting 404 not found feedback, when I specify jsonp i get no error message, but in the web console i can see a 404 error. in the browser when I visit the url it is returning valid json
This suggests that:
They don't support JSONP
They look at the HTTP headers and 404 your request to block access from Ajax (this isn't a good way to do that, the error code is misleading)
My question is how would I know when to use jsonp or json?
Usually by reading the documentation for the server you are trying to use
Also these service have been provided to me from an external source other than agreeing on json being returned how would I know if the problem is on my side or theirs?
Usually by working with whatever support is provided by the API provider (i.e. start with their documentation, then fall back to whatever means they provide for communicating with a human).
Due to Same Origin Policy your ajax request is allowed only if:
domain name, application layer protocol, and (in most browsers) port
number of the HTML document running the script are the same
In your case the application layer protocol is different, that's why your script fails.
Possible solutions are:
JSONP, which has to be provided by the server
CORS, which is a more 'elegant' and clean solution, but is not yet fully supported by IE (IE7 doesn't support it, IE8 has some limitations)
Answer taken from this link

Jsonp cross-domain ajax

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.

Call a external web page (cross-domain) with javascript

I'm trying to validate a feed, using the web service that is in this question.
But browser does not allow me to send a ajax GET request to another server. And there is a one second restriction per each request in that web service, so I can't mirror requests from my server.
This is my current jQuery code:
var reqUrl = "http://validator.w3.org/feed/check.cgi?url=" + encodeURIComponent(theUrl);
$.get(reqUrl, function(data) {
// do something
});
Isn't there any other way?
Ajax calls are not valid across different domains unless you use JSONP. JQuery-ajax-cross-domain is a similar question that may give you some insight. Also as noted by Luis in the comments, JSONP has to also be implemented on the domain that you are getting the data from.
Here is an example for jquery ajax(), but you may want to look into $.getJSON():
$.ajax({
url: 'http://yourUrl?callback=?',
dataType: 'jsonp',
success: processJSON
});
Another option is CORS (Cross Origin Resource Sharing), however, this requires that the other server to enable CORS which most likely will not happen in this case.
I searched google and found this. the third answer says that:
In computing, the same origin policy is an important security concept for a number of browser-side programming languages, such as JavaScript. The policy permits scripts running on pages originating from the same site to access each other's methods and properties with no specific restrictions, but prevents access to most methods and properties across pages on different sites.(source)
you'd better see the answers of this question.
I think you can't use JSONP because you haven't any access to W3C script.
Update (explanations)
I the question I linked to there is another way that I can explain it to you. if you set Access-Control-Allow-Origin header to * as the answer said you can send requests to another domains. and to use it easily in an MVC application you can see this solution. Good luck
Update2
to allow just http://validator.w3.org/ you just should set Access-Control-Allow-Origin to http://validator.w3.org/
for more details as answer said go here.
As said you can use JSONP but the endpoint must also implement it, And its only used if you are requesting json data from the call. It looks like you are retrieving html.
You can also implement a simple proxy in your domain that pulls the data from the external location and serves it to the ajax call. You can develop a simple proxy in php using for instance CURL.
Make sure you understand the implications of this security wise making sure for instance that you protect your proxy to only make calls to that external url (whitelisting).
Update: I just noticed you cannot use the proxy solution. And after following the link you have suggested I have came across CORS, which I didnt event know about. So apparentry you can set some headers when you are serving the pages in your domain that will instruct the browser that requests to some domains can be done.
Check this page for how to implement it:
http://enable-cors.org/
I have read that you might have to tweak it a bit to work with IE but it seems that all browsers are now implementing it.
I know this is an old question, but I myself have been trying to create AJAX requests to validator.w3.org as well, hit the exact same issues and stumbled on this SO question.
However, I did find a solution;
As people have already stated, the main problem here is that the server must issue valid CORS headers, i.e.
Access-Control-Allow-Origin: *
I used Fiddler to check the response headers from validator.w3.org and sure enough, the headers were not set. However, they also have another tool that does at validator.w3.org/nu/.
Here is an example: http://codepen.io/DDN-Shep/pen/ogdGgO/
$('form').on('submit', function(e) {
e.preventDefault();
var data = new FormData(this);
$.ajax({
url: 'http://validator.w3.org/nu/', // Trailing '/' is important or you get a 301 HTTP response status code
type: 'POST',
data: data,
processData: false, // Required for jQuery & FormData
contentType: false, // Set by FormData, required by the server
success: function(data, status, xhr) { /* TODO */ },
error: function(xhr, status, error) { /* TODO */ },
complete: function(xhr, status) { /* TODO */ }
});
});
If you are ever unsure whether or not a server allows CORS, you can use this very helpful online tool;
test-cors.org = http://client.cors-api.appspot.com/client

Categories