Ajax: GET call to api on Cross subdomain - ajax

I am trying to make ajax call to my crm api using this code but cant get this work without errors:
var username = 'admin';
var password = '1';
$.ajax
({
type: "GET",
dataType: 'json',
async: false,
url: "http://demo.espocrm.com/basic/api/v1/App/user",
headers: {
"Authorization": "Basic " + btoa(username + ":" + password)
}
})
.done(function(){
alert('Authenticated!')
})
.fail(function(){
alert('Error!')
});
the call come from www.domain.com to crm.domain.com
in the .htaccess on crm.domain.com i have this code:
<ifModule mod_headers.c>
Header set Access-Control-Allow-Origin "http://www.domain.com"
Header set Access-Control-Allow-Methods "OPTIONS, GET, PUT, POST, DELETE, HEAD"
Header set Access-Control-Max-Age "1800"
</ifModule>
I also tried to use jsnot and use this url: http://demo.espocrm.com/basic/api/v1/App/user?callback=?
the errors are:
OPTIONS http://crm.domain.com/api/v1/App/user?_=1437237158381 500 (Internal Server Error)
XMLHttpRequest cannot load http://crm.domain.com/api/v1/App/user?_=1437237158381. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.domain.com' is therefore not allowed access. The response had HTTP status code 500.
when i use jsnop:
GET http://crm.domain.com/api/v1/App/user?callback=jQuery21404605716757941991_1437238651212&_=1437238651213

Related

Cross origin blocking despite subdomain exists in policy

Hello I am trying to use cross origin from a subdomain (app.example.com) to www.example.com. When I try to execute the ajax I receive this:
XMLHttpRequest cannot load http://app.example.com/. The 'Access-Control-Allow-Origin' header has a value 'http://app.edentalbook.com' that is not equal to the supplied origin. Origin 'null' is therefore not allowed access.
I dont understand how I should use it..In my apache conf file I have those lines in order to enable cross origing policy:
Header always set Access-Control-Allow-Origin "http://app.example.com"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding"
Header always set Access-Control-Allow-Credentials "true"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
My ajax call:
$.ajax({
method: "GET",
url:'http://www.example.com/index.php?logout',
crossDomain: true,
dataType: "json",
xhrFields: {
withCredentials: false
},
success: function(data){
loginPresta(email,password,companyName);
if(data == 'ok') {
}
},
error:function(data){
}
});

FireFox doesn't send cross-domain ajax?

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.

Cross domain ajax hits error even that the status came back is 200

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.

simple ajax request to localhost nodejs server

I wrote very simple server :
/* Creating server */
var server = http.createServer(function (request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("Hello World\n");
});
/*Start listening*/
server.listen(8000);
I run it using nodejs.
Now i want to write simple client that use ajax call to send request to server and print response (Hello World)
Here javascript of clinet:
$.ajax({
type: "GET",
url: "http://127.0.0.1:8000/" ,
success: function (data) {
console.log(data.toString);
}
});
When I open client html file i get following error in console:
XMLHttpRequest cannot load http://127.0.0.1:8000/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
I tried adding to ajax call following:
$.ajax({
type: "GET",
url: "http://127.0.0.1:8000/" ,
dataType: 'jsonp',
crossDomain: true,
success: function (data) {
console.log(data.toString);
}
});
But then i get
Resource interpreted as Script but transferred with MIME type text/plain: "http://127.0.0.1:8000/?callback=jQuery211046317202714271843_1410340033163&_=1410340033164".
Anyone can explain what i did wrong and perhaps how to fix it?
Many thanks!
To overcome the CORS, in your node.js file write the below, based on what you need:
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
The first error is caused by CORS (Cross Origin Resource Sharing) policy. It's rule by all browsers that you cannot make a request to a remote server in AJAX other than to the current server the script/page was loaded from unless that remote server allows it via Access-Control-Allow-Origin header.
I suggest serving the page from the same Node.js server. Then it will work. Example, when the request comes to root / page, then serve the index.html file, otherwise, server whatever other content you want.
var http = require('http'),
fs = require('fs');
/* Creating server */
var server = http.createServer(function (request, response) {
if (request.url == '/' || request.url == '/index.html') {
var fileStream = fs.createReadStream('./index.html');
fileStream.pipe(response);
} else {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("Hello World\n");
}
});
/*Start listening*/
server.listen(8000);

Can't retrieve my x-api-key from my request header with CORS enabled. Why?

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
}
});

Resources