Whenever I make a webapp and I get a CORS problem, I start making coffee. After screwing with it for a while I manage to get it working but this time it's not and I need help.
Here is the client side code:
$http({method: 'GET', url: 'http://localhost:3000/api/symbol/junk',
headers:{
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, X-Requested-With',
'X-Random-Shit':'123123123'
}})
.success(function(d){ console.log( "yay" ); })
.error(function(d){ console.log( "nope" ); });
The server side is a regular node.js with an express app. I have an extention called cors and it's being used with express this way:
var app = express();
app.configure(function(){
app.use(express.bodyParser());
app.use(app.router);
app.use(cors({origin:"*"}));
});
app.listen(3000);
app.get('/', function(req, res){
res.end("ok");
});
If I do
curl -v -H "Origin: https://github.com" http://localhost:3000/
It gets back with:
* Adding handle: conn: 0x7ff991800000
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x7ff991800000) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 3000 (#0)
* Trying ::1...
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:3000
> Accept: */*
> Origin: https://github.com
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Date: Tue, 24 Dec 2013 03:23:40 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
* Connection #0 to host localhost left intact
ok
If I run the client side code, it brigs up this error:
OPTIONS http://localhost:3000/api/symbol/junk No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. angular.js:7889
XMLHttpRequest cannot load http://localhost:3000/api/symbol/junk. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8000' is therefore not allowed access. localhost/:1
nope
Checking Chromes headers:
Request URL:http://localhost:3000/api/symbol/junk
Request Method:OPTIONS
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8,es;q=0.6,pt;q=0.4
Access-Control-Request-Headers:access-control-allow-origin, accept, access-control-allow-methods, access-control-allow-headers, x-random-shit
Access-Control-Request-Method:GET
Cache-Control:max-age=0
Connection:keep-alive
Host:localhost:3000
Origin:http://localhost:8000
Referer:http://localhost:8000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Response Headersview source
Allow:GET
Connection:keep-alive
Content-Length:3
Content-Type:text/html; charset=utf-8
Date:Tue, 24 Dec 2013 03:27:45 GMT
X-Powered-By:Express
Checking the request headers I see that my test string X-Random-Shit is present in the "Access-Control-Request-Headers" but it's value is not there. Also, in my head I was expecting to see one line for each one of the headers I am setting, not a blob.
UPDATES ---
I changed my frontend to jQuery instead of Angular and made my backend like this:
var app = express();
app.configure(function(){
app.use(express.bodyParser());
app.use(app.router);
});
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'OPTIONS,GET,POST,PUT,DELETE');
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
if ('OPTIONS' == req.method){
return res.send(200);
}
next();
});
app.get('/', function(req, res){
res.end("ok");
});
Now it works with GET but does not with anything else (PUT, POST..).
I'll see if any of you comes up with a solution. In the mean time in throwing the RESTful concept out the window and making everything with GETs.
$http is an AngularJS service for reading data from remote servers.
CORS error due to browser's same origin policy. To get around this, you need to tell your browser to enable your client and your server to share resources while being of different origins. In other words, you need to enable cross-origin resource sharing or CORS in your application.
To add or overwrite these defaults, simply add or remove a property from these configuration objects. To add headers for an HTTP method other than POST or PUT, simply add a new object with the lowercased HTTP method name as the key, e.g. $httpProvider. defaults.
I'm new to AngularJS and I came across this CORS problem, almost lost my mind! Luckily i found a way to fix this. So here it goes....
My problem was, when I use AngularJS $resource in sending API requests I'm getting this error message XMLHttpRequest cannot load http://website.com. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
Yup, I already added callback="JSON_CALLBACK" and it didn't work.
What I did to fix it the problem, instead of using GET method or resorting to $http.get, I've used JSONP. Just replace GET method with JSONP and change the api response format to JSONP as well.
myApp.factory('myFactory', ['$resource', function($resource) { return $resource( 'http://website.com/api/:apiMethod', { callback: "JSON_CALLBACK", format:'jsonp' }, { method1: { method: 'JSONP', params: { apiMethod: 'hello world' } }, method2: { method: 'JSONP', params: { apiMethod: 'hey ho!' } } } ); }]);
I hope someone find this helpful. :)
I've had success with express and editing the res.header
. Mine matches yours pretty closely but I have a different Allow-Headers
as noted below:
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
I'm also using Angular and Node/Express, but I don't have the headers called out in the Angular code only the node/express
Writing this middleware might help !
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
for details visit http://enable-cors.org/server_expressjs.html
Adding below to server.js resolved mine
server.post('/your-rest-endpt/*', function(req,res){
console.log('');
console.log('req.url: '+req.url);
console.log('req.headers: ');
console.dir(req.headers);
console.log('req.body: ');
console.dir(req.body);
var options = {
host: 'restAPI-IP' + ':' + '8080'
, protocol: 'http'
, pathname: 'your-rest-endpt/'
};
console.log('options: ');
console.dir(options);
var reqUrl = url.format(options);
console.log("Forward URL: "+reqUrl);
var parsedUrl = url.parse(req.url, true);
console.log('parsedUrl: ');
console.dir(parsedUrl);
var queryParams = parsedUrl.query;
var path = parsedUrl.path;
var substr = path.substring(path.lastIndexOf("rest/"));
console.log('substr: ');
console.dir(substr);
reqUrl += substr;
console.log("Final Forward URL: "+reqUrl);
var newHeaders = {
};
//Deep-copy it, clone it, but not point to me in shallow way...
for (var headerKey in req.headers) {
newHeaders[headerKey] = req.headers[headerKey];
};
var newBody = (req.body == null || req.body == undefined ? {} : req.body);
if (newHeaders['Content-type'] == null
|| newHeaders['Content-type'] == undefined) {
newHeaders['Content-type'] = 'application/json';
newBody = JSON.stringify(newBody);
}
var requestOptions = {
headers: {
'Content-type': 'application/json'
}
,body: newBody
,method: 'POST'
};
console.log("server.js : routes to URL : "+ reqUrl);
request(reqUrl, requestOptions, function(error, response, body){
if(error) {
console.log('The error from Tomcat is --> ' + error.toString());
console.dir(error);
//return false;
}
if (response.statusCode != null
&& response.statusCode != undefined
&& response.headers != null
&& response.headers != undefined) {
res.writeHead(response.statusCode, response.headers);
} else {
//404 Not Found
res.writeHead(404);
}
if (body != null
&& body != undefined) {
res.write(body);
}
res.end();
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With