No 'Access-control-allow-origin' header is present on the requested resource error with json and jquery - javascript

I use an API that is on a different server and i got an CORS error I think. The strange thing is that it first worked with no problem, then i got this error message
XMLHttpRequest cannot load http://www.thecocktaildb.com/api/json/v1/1/random.php? tagmode=any&type=POST&format=jsonp. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'myadress.com' is therefore not allowed acces
i added crossDomain: "true" and it worked for a day. Now it doesn't work again and i've searched and tried a lot of solutions i've found. But nothing works. What is the problem and how do i fix it? Tried jsonp instead of json with and without type:post and the &callback=? does nothing. I've even installed the CORS enable extension for chrome. But alwways the same error, I have no control over the API itself or the server hosting it. How can I fix this? Below is my code.
function random() {
$(document).ready(function () {
$.getJSON("http://www.thecocktaildb.com/api/json/v1/1/random.php", {
tagmode: "any",
type: "POST",
format: 'jsonp',
crossDomain: "true"
}, function (data) {
console.log(data);
var result = "";
$.each(data.drinks, function (index, value) {
result += "<p>" + value.idDrink + "<p>";
result += "<p>" + value.strDrink + "<p>";
});
$('#result').html(result);
console.log(result);
});
});
}

I think you can make some modification for bypass CORS error. but target environment can also block CORS request. When I used Paypal checkout, I encountered same problem. Paypal environment doesn't accept CORS request.
So that you can try to make this call over server side.

If I understood it right you are doing an AJAX call to a different domain than your page is on. So the browser is blocking it as it usually allows a request in the same origin for security reasons. You need to do something different when you want to do a cross-domain request. A tutorial about how to achieve that is Using CORS.
Regular web pages can use the XMLHttpRequest object to send and
receive data from remote servers, but they're limited by the same
origin policy. Extensions aren't so limited. An extension can talk to
remote servers outside of its origin, as long as it first requests
cross-origin permissions.
Solution :
For allowing access to specific domain only:
response.addHeader("Access-Control-Allow-Origin", "http://www.thecocktaildb.com");
Check this blog post.

Related

JQuery / AJAX: Cross-Origin Request Blocked

I have the following script (simplfied) that grabs some data from a local php file:
$(document).ready(function(){
var current_date = "x=y";
$.ajax
({
url: 'work/get_cal.php',
type: 'post',
data : current_date,
async: false,
success: function(result)
{
alert('never gets this far');
}
});
});
However I get a cross domain error, even though everything is on the same server. Has anyone had this issue before?
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://www.mywebsite.co.uk/work/get_cal.php. (Reason: CORS header 'Access-Control-Allow-Origin' missing).
Add following line to get_cal.php
header('Access-Control-Allow-Origin: *');
This will allow to make Cross-Origin Request.
From comments to the original question for future Googlers.
The code used absolute paths and ended up in different domain "level" when the page was accessed with www and the script was requesting without www. This caused CORS problem.
Same Origin Policy permits running scripts in a browser and allows making requests to pages on with the SAME URI Scheme, hostname and port number. This is implemented for security within most of the browsers.
I personally use Chrome with Web Security Disabled during testing. Use the --disable-web-security parameter to enable this in your Chrome.
I strongly advice creating a seperate shortcut for development & testing purposes and NOT to use this option for your regular browsing...
"C:\<path_to_chrome_folder>\chrome.exe" --user-data-dir="C:/Chrome dev session" --disable-web-security
--user-data-dir is used to store the session details and other browser data, thus keeping is separate from your regular browsing data.
--disable-web-security disables the security and thus the Same Origin Policy warning.
Hope this helps...!

Adobe Connect API with Jquery

I am trying to create a simple login form for my Adobe Connect account, however it's not working, I'm getting the error:
No 'Access-Control-Allow-Origin' header
However I'm doing other Ajax calls just fine on my machine.
Here's some example code that I'm using.
var request $.ajax({
url: 'http://example.com/api/xml?action=login&login=' + username + '&password=' + password
type: "GET"
});
request.done(function(){
...
})
Does anyone have any suggestions?
Your local machine calls are working because you're making calls inside the same domain. As soon as you try to do ajax calls to something outside the bounds of the caller's domain you'll run into issues with the browser's Same-Origin policy.
Basically it's a security policy that allows scripts to run on pages originating from the same site (comprised by the combination between schema, hostname and port. eg. mysite != mysite:8080) So if you have an ajax call executed from a site running on mysite to a site running on mysite:8080, the browser will consider this a same-origin policy hence blocking that request.
You should read about CORS (Cross-Origin Resource Sharing) in order to find options to help you relax the same-origin policy.

Why this won't fetch source code?

This code should fetch the HTML source of http://yahoo.com/(index.html), and show it in dialog.
$.ajax({ url: 'http://yahoo.com', success: function(data) {
alert(data);
}
});
However, it won't do anything...
What's wrong with my code?
By default, you're not allowed to make cross domain requests. This violate the Cross Origin policy.
To make it work the requested domain must emit headers that allow the requesting domain.
I've got a tutorial on how to set and use the CORS policy: http://fritsvancampen.wordpress.com/2013/02/03/cross-site-origin-requests-aka-cross-origin-resource-sharing/
but if you want to fetch data from Yahoo you need control over their domain .. and that's not gonna happen ;)
Ajax is not used for your purpose . you have to used like this
$content = file_get_contents('http://www.yahoo.com/');
print_r($content);
Or this could be helpful for you
http://toolspot.org/extract-website-data.php

Sending POST message with AJAX Problem

I am currently trying to send a POST message which works fine except for the error that there are not correct credentials. However, after I add the credentials header, the message type is changed into OPTIONS and fails. I do not understand how adding a header causes the type to change to OPTIONS. Any help would be appreciated.
ajaxRequest = $j.ajax({
url: url,
type: 'POST',
beforeSend : function(req) {
req.setRequestHeader('Authorization', auth),
}
success: function(data, status) {
console.log("Success!!");
console.log(data);
console.log(status);
},
error: function(xhr, desc, err) {
console.log(xhr);
alert('fail')
console.log("Desc: " + desc + "\nErr:" + err);
}
});
EDIT: just to be more clear, I can literally go in and comment out the setRequestHeader function and it sends the message POST.
The problem you're encountering is because of cross-domain restrictions when using AJAX. When you try to set an authorization header, the browser issues what's known as a pre-flight request to see if the server will accept requests from this domain.
A pre-flight request is typically sent as an OPTIONS request. If the server you're invoking doesn't return an Access-Control-Allow-Origin header that matches your domain, the AJAX request is blocked.
There's more on this here: Cross-Origin Resource Sharing
"User agents can discover via a preflight request whether a cross-origin resource is prepared to accept requests, using a non-simple method, from a given origin."
I've run into the same problem- there are a few possible workarounds depending on your scenario.
If you have any way of setting the above mentioned header on the 3rd party server (some applications/services offer this) then that's probably the easiest way.
There's also a javascript library called EasyXDM that may work for you, but again, it will only be of use if you have access to the 3rd party server to upload a configuration file for this library.
Other options to investigate are PostMessage and Cross Domain Iframe communication. The latter is more of an old-school hack, the former is the recommended approach for newer browsers. It won't work for IE6/7.
The option we will probably end up using is a simple proxy- invoke our own server with the AJAX request, and on the server invoke the 3rd party server. This avoids the cross domain issue entirely, and has other advantages for our scenario.
I guess this is a problem in Internet Explorer. without explicitly telling the request-method (POST|GET) the request header doesn't contain the custom-header in IE, but it works in other browsers.
Yet try to post this in the bugs for jquery. Also try in other browsers.
Edit 1 : I saw this as a bug in jQuery 1.4.x .... I reported a bug report now.
The OPTIONS response happens when the server does not know how to respond to the ajax request.
I've seen it happen often when trying to post to a third-party domain (i.e. cross-site posting)
The OPTIONS method represents a request for information about the communication options available on the request/response chain identified by the Request-URI. This method allows the client to determine the options and/or requirements associated with a resource, or the capabilities of a server, without implying a resource action or initiating a resource retrieval.
Have you tried:
Having some sort of callback on the url that is being posted to?
Explicitly setting the headers (I'm assuming you're using PHP) on the url that is being posted to?

Question about making XHR requests

I'm not sure why but I haven't really been able to find the right resource for this which helps me understand the best practice here, but say I have an application, that I want to make an Ajax request to another application.
Say app A's domain name is: www.example.com, and I want to make a request to www.someapplication.com
Can I do something like this? (jQuery in this case)
$.ajax({
url: 'http://www.someapplication.com/items',
dataType: 'json',
data: "search=butter",
success: function(data){
console.log(data);
}
});
When I go the address (http://www.someapplication.com/items?search=butter&format=json) in my browser it returns a 200 response and the content in the json format which I requested however when the above JS executes it receives a 200 response but no content.
Is this because my sever at someapplication.com is recognizing this as an XSS attack and denying a response?
One though I had is should the request go to a .js file? I've noticed this in the design of other applications, for example: http://www.someapplication.com/search.js... err rather what is wrong with my concepts, am I missing something huge here about XSS, and Ajax?
It's indeed due to the same origin policy. If you have control over the remote server, you can also just add HTTP Access-Control headers in the server side. This way you're basically controlling from the server side on whether the client who has fired the XMLHttpRequest is allowed to process the response. Any recent (and decent) webbrowser will take action accordingly.
Here's a PHP-targeted example how to set the headers accordingly.
header('Access-Control-Allow-Origin: *'); // Everone may process the response.
header('Access-Control-Max-Age: 604800'); // Client may cache this for one week.
header('Access-Control-Allow-Methods: GET, POST'); // Allowed request methods.
The key is Access-Control-Allow-Origin: *. This informs the client that requests originating from * (in fact, everywhere) is allowed to process the response. If you set it to for example Access-Control-Allow-Origin: http://example.com, then the webbrowser may only process the response when the initial page is been served from the mentioned domain.
A lot of existing JSON services also uses this, under each the ones of Google.
See also:
MDC - HTTP Access Control
In the answer of Nick you fill see how to use JSONP. I want to add you a recommendation how to modify your $.ajax code to see that you have an error inside of success handler. I described it in jQuery $.ajax, error handler doesn't work. Probably the bug in jQuery after the change http://dev.jquery.com/changeset/6432 will be fixed soon. Till the time you can use
success: function(data, textStatus, xhr){
if (xhr.readyState === 4 && xhr.status === 0) {
alert('"error flag\" is true. It means that we have a network error '+
'or abortion (for example because of Same Origin Policy restrictions)');
}
},
error: function(xhr, textStatus, errorThrown) {
if (textStatus !== null) {
alert("error: " + textStatus);
} else if (errorThrown !== null) {
alert("exception: " + errorThrown.message);
} else {
alert ("error");
}
}
In this case you will see "exception: access denied" error in IE and
"error flag" is true. It means that we have a network error or abortion
(for example because of Same Origin Policy restrictions)
error in other web browsers in case of Same Origin Policy error.
By the way in my experiments browser return xhr.status=0 and not 200 in case of Same Origin Policy error.
What you're hitting is the same origin policy, the remote domain needs to support JSONP in order to work, otherwise XmlHttpRequest is prevented (by the browser) from seeing the content.
Once that's setup, in jQuery you'd trigger JSONP behavior by setting the dataType option to jsonp instead, like this:
$.ajax({
url: 'http://www.someapplication.com/items',
dataType: 'jsonp',
data: "search=butter",
success: function(data){
console.log(data);
}
});
This requests the content in an entirely different way, by adding a <script> element to the page...so the domain must support JSONP, otherwise you'll see some flavor of syntax error when the response comes back.
While cross domain XHR is not available in all browsers yet, you can do a gateway made from simple PHP file:
<?php
echo file_get_contents($_GET['url']);
?>
Then you just use proper url: gateway.php?url=http://www.someapplication.com/items.
Maybe not ideal solution, but it works.
EDIT:
Consider declaring in PHP file urls (or just domains) you want to use to avoid possible abuse of the gateway, e.g.:
<?php
$urls = array();
$urls[0] = 'http://www.someapplication.com/items';
echo file_get_contents($urls[$_GET['id']]);
?>

Categories

Resources