Here is a problem: when user make authorisation on one server (e.g. a.com) he should be authorised (over jQuery-ajax) on another server (e.g. b.com) - the user-DB is shared for both this sites. Js-code written is
var form = jQuery('#auth_form');
var data = form.serialize();
var url = 'http://www.b.com/auth';
jQuery.ajax({
url: url,
crossDomain: true,
type: 'POST',
dataType: 'html',
data: data,
xhrFields: {
withCredentials: true
},
success: function (html) {
},
error: function (jqXHR, textStatus) {
}
});
When server send response, he set some of header
header("Access-Control-Allow-Origin: http://www.a.com");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: POST,GET,OPTION");
header("Access-Control-Max-Age: 1000");
header("Access-Control-Allow-Headers: x-requested-with, Content-Type, origin, authorization, accept, client-security-token");
It works fine in Chrome and Opera, but ForeFox seems even dousn't send request to server and writes something like this in console log:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://www.b.com. This can be fixed by moving the resource to the same domain or enabling CORS.
FireFox is latest version (37.0.1) and it's written that version 3.5+ supports CORS and i don't understand what is going wrong? I've tried look network through Fiddler - and i don't see request to b.com from FireFox (from Chrome i see one - everything is Ok). I've tried manage FireFox options (capability.policy.default.XMLHttpRequest.open = allAccess), but it doesn't work. Where is any solution? Any help will be appreciated.
Related
I'm having a problem to make a call to a rest API.
In the document (FAQ) of the web application there is an example that use AJAX request to make the call. Here an example:
var url = 'https://example.com/yyy';
$.ajax({
type: 'POST',
url: url,
cache: false,
data: {
opt: JSON.stringify(example)
},
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (result)
{
console.log(result);
} });
I created a local page with this code to made the post to the API that is located on a remote server but I receive an error about CORS.
Is there any solution to circumvent this problem? I tried to use firefox plugin to allow CORS but it didn't solve the problem. The session is authenticated via form before use the endpoint.
I see several issues:
Try to run the code from a domain and not from local disk (alternatively you can consider using https://crossorigin.me/ )
How does the authentication work? if with cookies you need to add withCredentials to the ajax request.
Make sure the API returns Access-Control-Allow-Origin: foo header where foo is the domain your code runs in. If you also used withCredentials, you should add Access-Control-Allow-Credentials: true
I am sending cross domain ajax request, the response comes back with status 200. I also see that the request arrives to the server.
I have this in my server:
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");
context.Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
context.Response.Headers.Add("Access-Control-Allow-Headers", "*");
This is on the client:
$.ajax({
type: "POST",
url: this.SERVER + url,
data: data,
xhrFields: {
withCredentials: true
},
success: function (a, b) {
debugger;
alert("sdsd");
},error : function(a,b) {
debugger;
},
dataType: 'json'
});
this is the request from the chrome browser
In firefox its I get the error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:2000/PageHandler.ashx. This can be fixed by moving the resource to the same domain or enabling CORS
My wild guess is that since you are sending the Access-Control-Allow-Credentials header you cannot put * in Access-Control-Allow-Origin. Try specifying the origin as that of your JavaScript client.
I am basing this on the following piece of information from the Mozilla Developer Networks Documentation on CORS:
The origin parameter specifies a URI that may access the resource.
The browser must enforce this. For requests without credentials, the
server may specify "*" as a wildcard, thereby allowing any origin to
access the resource.
I'm trying to access an API service (via XMLHttpRequest/ajax) hosted on a sub-domain (ie: a client on app.samedomain.com will call out to api.samedomain.com) that requires specific headers to be set for security purposes, but I keep getting Access is denied errors. All the solutions I've found say the client/end user must add the site to the "Trusted Sites" security zone, but obviously this is not a real solution. What do I need to do to access an external site with specific headers?
Example Code:
var getUserById = function (user, callback, error) {
$.support.cors = true;
var endpoint = _getApiVersion() + '/person/model/' + user.userId;
var _headers = _setHeaders(endpoint, null, user, 'GET');
$.ajax({
type: 'GET',
beforeSend: function (request)
{
request.setRequestHeader("api-key", _headers['api-key']);
request.setRequestHeader("timestamp", _headers['timestamp']);
request.setRequestHeader("content-md5", _headers['content-md5']);
request.setRequestHeader("content-type", _headers['content-type']);
request.setRequestHeader("signature", _headers['signature']);
request.setRequestHeader("Access-Control-Allow-Origin", "*");
},
url: _getBaseUrl() + endpoint,
data: null,
contentType: 'application/json',
dataType: 'json',
success: callback,
error: error
});
};
Thanks in advance,
Dan
Are you trying to get data that is not in the same domain as the requester? If that is the case the only option is to proxy the original request via a service so XMLHttpRequest has access to it.
"Access-Control-Allow-Origin" is a response header, not a request header. It is something that the server should send back to IE as part of the response.
If that still doesn't work, you might want to try firing up the F12 Network tool in the IE Dev tools to see if you can get more detail into where in the process the request is failing (Ex: It might be failing on a CORS preflight OPTIONS request).
Also, Rather than using "Access-Control-Allow-Origin: *", you should use "Access-Control-Allow-Origin:app.samedomain.com" to control which domains can access the API
To read more about CORS, check http://www.w3.org/wiki/CORS
Aside from that, it feels like an order of operations thing. All this should be before the callbacks.
type: 'GET',
url: _getBaseUrl() + endpoint,
data: null,
contentType: 'application/json',
dataType: 'json',
I'm working with CodeIgniter2 Rest API and AJAX to make requests from a smartphone with PhoneGap to a AWS server with apache.
Everything was working fine when working on my localhost/browser.
But when trying to set up a distant server things got bad.
I have configured my server properly with CORS so that it allows external requests as explained here :
http://dev.nuclearrooster.com/2011/01/03/cors-with-apache-mod_headers-and-htaccess/
To secure the API, I have been setting up an API KEY that I have to pass in the header of my request like so:
$.ajax({
type:"GET",
url: server_url + 'user/available',
headers: { 'X-API-KEY': key },
dataType: 'json'
});
But then, after seeing my ajax called being refused because of an invalid API Key, I have been trying to make sure the server received the key. and it doesnt. when I try to echo my key, its empty.
I can see in my debug console the following:
Request header field X-API-KEY is not allowed by Access-Control-Allow-Headers.
So I have been modifying my .htaccess following this post:
Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type, x-api-key"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
so now, the message is gone but the problem still remains the same ... why ?
How can I transmit this X-API-KEY through my AJAX call Header so I can authentificate my users ?
Many Thanks
I faced this problem and with weeks of tweaking I was able to get it to work with a hack of a job... I can't remember the exact part that did fix it but will provide with what I am currently using.
Server Side
function __construct(){
parent::__construct();
header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("Access-Control-Allow-Headers: X-API-KEY");
}
function available_options(){
$this->response(array('response' => array()), 200);
}
Client Side
function sendData(dataToSend, successCallback) {
window.default_headers['X-API-KEY'] = '_KEY_';
return $.ajax({
type: "POST",
url: server_url + 'user/available',
data: { data : JSON.stringify(dataToSend) }, // serializes the form's elements.
dataType: 'json',
headers: window.default_headers,
xhrFields: {
withCredentials: true
}
});
}
Since you're using a GET request, possibly using JSONP would be of more use, this avoids cross domain requests.
JSONP Request
$.ajax({
type : "GET",
dataType : "jsonp",
url: server_url + "user/available?callback=?", // ?callback=?
success: function(data){
// do stuff with data
}
});
I have this webapp where I make a post request using Ajax from Domain A to a rest service on Domain B
Domain B has been set up to serve the response with the CORS Access-Control* headers in order to get the cross-domain posting to work
Headers in response from domain B:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: POST GET OPTIONS
Access-Control-Allow-Origin: https://sub.domain-a.com
Access-Control-Max-Age: 180
The Ajax code
$.ajax({
url: 'https://sub.domain-b.com',
type: 'POST',
contentType: 'application/json',
headers: {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
},
data: json,
dataType: 'json',
xhrFields: {
withCredentials: true
},
success: function (data) {
},
error: function (jqXHR, textStatus, errorThrown) {
}
});
I am logged in on both domains and my request sends the necessary cookie (withCredentials=true), but I am still getting a 403 Forbidden from the response
Both domains are using SSL a certificate
I am beginning to wonder if the SSL's are causing the problem as this worked before and I am getting nothing in my logs
Are there anyone here that have any experience with something similar?
Any pointers?
It could be something similar to this issue:
Pre-flight OPTIONS request failing over HTTPS
Typically when the issue is with SSL and the preflight request though you wouldn't get back a 403, you'd just get the OPTIONS request aborting.
How does the service authenticate and authorise? Are you using self-signed certificates? It sounds like you're correct in thinking that SSL is causing the issue and without more info it's hard to say what your specific problem is.