How to send both data and header to a server? - angularjs

I want to send a header to a server using http call POST request.
When I send the header only, everything is ok.
but when I add some data to the call, I get an error:
http://localhost:3000/test_post.
Request header field Content-Type is not
allowed by Access-Control-Allow-Headers in preflight response.
I use node.js as the server side language, this is the code for the CORS settings:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Expose-Headers", "x-auth");
res.header("Access-Control-Allow-Headers", "x-auth");
next();
});
This is the $http call with angular:
$http({
method: 'POST',
data: {name: 'Dani'},
url: 'http://localhost:3000/test_post'
headers: {
'x-auth': 'some token'
}
}).then(function successCallback(response) {
console.log(response.data);
}, function errorCallback(response) {
console.log('error');
});
I know problem is about the CORS, but I don't know what to modify there,
If I remove res.header("Access-Control-Allow-Headers", "x-auth"); from the CORS I can get the data on the server but not the Header.
How can I get them both?
Hope you can help me with that, Thank you.

Related

Cannot fetch from localhost with Authorization header

I'm having a hard time sending a get request to my expressjs backend with the fetch method.
fetch('http://localhost:9000', { method: 'GET', headers: { Authorization: `Bearer ${accessToken.accessToken}` }}).then(() => {
debugger
}).catch((error) => {
debugger
})
Based on what I could read, this seems correct - The request is however not reaching the API.
I tried constructing the options object like so, without any luck:
const options = {
method: "GET",
headers: headers
};
Without the headers, my request reaches the API. Anyway, the error that I'm getting is this:
error: TypeError: Failed to fetch
If you make that request from an origin other than http://localhost:9000, the Authorization header will cause the browser to make a CORS preflight request OPTIONS http://localhost:9000 before the GET request, and if that fails, the GET request would not be made.
You must ensure that your server handles the preflight, e.g., through the cors middleware.
So I found a solution, basically I added this middleware in my Express application to allow CORS,
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "*");
res.header("Access-Control-Allow-Methods", "*");
next();
});

angular $http request from 80 port to another port

I am trying to hit a node api with port 3000 on local server from a angular 1 project using $http method but I am getting this error:
XMLHttpRequest cannot load http://localhost:3000/login. Request header
field Authorization is not allowed by Access-Control-Allow-Headers in
preflight response.
I also added the Access-Control-Allow-Origin : * in node js as :
req.on('end', function() {
req.rawBody = req.rawBody.toString('utf8');
res.setHeader('Access-Control-Allow-Origin', 'http://localhost');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', '*');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', '*');
// 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', false);
next();
});
And my angular code is :
var req = {
method: 'POST',
url: 'http://localhost:3000/login',
headers: {
'Content-Type': 'application/json',
// 'cache-control': 'no-cache'
},
data: { username: username, password: password },
json: true
};
$http(req).then(function successCallback(response){
console.log(response);
}, function errorCallback(response){
console.log("Error : ");
console.log(response);
});
But still I am getting this error.
The error is in the preflight response as specified.
So you need to handle the OPTIONS method :
req.on('end', function() {
req.rawBody = req.rawBody.toString('utf8');
res.setHeader('Access-Control-Allow-Origin', 'http://localhost');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', '*');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', '*');
// 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', false);
if (req.method === "OPTIONS") {
return res.status(200).end();
}
return next();
});
This is due to the way browsers handle cross-origin request. An OPTIONS request (preflight) is sent before your POST to get allowed origins, headers and methods.

AngularJS + ServiceStack + Node.js as a proxxy?

I have created an application in angularjs. The server side is covered by servicestack, I'd like to process a json file that is provided by the servicestack application. To do it I use following code in angularjs:
taskListApp.factory('Fact', function ($resource) {
return $resource("http://localhost:55267/hello?format=json", {},
{
query: {method: 'GET', url: "http://localhost:55267/hello?format=json"},
});
});
However I get the error in console about same origin policy, missing CORS header.
I'm trying to use the default node.js template to create a proxxy server, but I'm clueless about what ports should I use. Any headers?
EDIT:
this is my node.js code, which returns unhandled 'error' error
httpProxy.createServer({
target:'http://localhost:55267'
}).listen(8003);
http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(55267);
Not sure if this will resolve the issue with node but if you want to add CORS Response Headers to the ServiceStack response you need to register the CORS plugin in your AppHost's Configure():
Plugins.Add(new CorsFeature());
If you want to add CORS Response Headers to the ServiceStack response. Please add the below lines:
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

Ionic http post to external url

Im trying to send a post to a url with Ionic using angular, but i have the response:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access. The response had HTTP status code 404.
I know that the external service is working, because i tested it by ajax and everything works perfectly...
Below the code used in AngularJS (Ionic) and Ajax:
Ionic:
var loginServiceUrl = 'http://url.com.br'; //It is not the real one
var loginServiceData = {
email: email#email.com.br
senha: 1234
};
$http.post(loginServiceUrl, loginServiceData).
then(function (res){
console.log(res);
});
Ajax:
$.ajax({
type: "POST",
url : 'http://url.com.br', //It is not the real one
data : {email: 'email#email.com.br', senha: '1234'},
success: function(result) {
$('html').text(JSON.stringify(result));
}
});
Does anyone know why I get the post via ajax on my localhost and not with the ionic, also localhost?
Check this out. It is well explained how to handle issues like yours --> http://blog.ionic.io/handling-cors-issues-in-ionic/
Try to add headers in your POST request.
//example of DataToSend
var DataToSend = {
userID: deviceID,
coordLat : pos.coords.latitude,
coordLon: pos.coords.longitude
};
$http({
method: 'POST',
url: 'http://url.com.br',
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
data: DataToSend
})
CORS has nothing to do with your frontend.
Before sending the POST request, browser send a OPTIONS request to the server to check if call from your domain is allowed or not.
Since, you are getting Status 404, that means your server is not handling the OPTIONS request
1. Allow the OPTIONS request (same as POST)
Now come to second part i.e " Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' "
After allowing the OPTIONS request, now set the response header of OPTIONS request (Browser will check the response of OPTIONS request and then process the POST request only if there is 'Access-Control-Allow-Origin' present in the OPTIONS response.
2. Set the response headers of OPTIONS request
response().setHeader("Access-Control-Allow-Origin", "*");
response().setHeader("Allow", "*");
response().setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS");
response().setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent");
Example..
(In Java)
Router:
OPTIONS /*all
controllers.Application.preflight(all)
Controller Function:
public static Result preflight(String all) {
response().setHeader("Access-Control-Allow-Origin", "*");
response().setHeader("Allow", "*");
response().setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS");
response().setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent, Auth-Token");
return ok();
}
Hope this will solve your problem.
Cheers

CORS issue for Ionic + express

I have created an application that is accessing/fetching the data from mongo/node+express, which is on different domain(eg domain_name).
The code for the get function is :
var request = $http({
method: 'GET',
url: 'https://domain_name.users.io/categories/list',
withCredentials: true /* to get the Cookie value generated at server-side */
});
At the express side, have added the following code in order to avoid the CORS issue:
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods","GET,PUT,POST,DELETE,OPTIONS");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", "true");
For the above, i am getting the following error:
XMLHttpRequest cannot load https://domain_name.users.io/data/list. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost:8100' is therefore not allowed access.
I have checked the API "https://domain_name.users.io/data/list" and there is no issue with it as i can see the data(when hit on browser).
Could someone please help me for the same
Besides * is too permissive and would defeat use of credentials. So use https://domain_name.users.io/data/list rather than you use *.
You can't do like * because this is a part of security and if you want to allow credentials then your Access-Control-Allow-Origin must not use *.
For more please read here.
Must set the headers:
var request = $http({
method: 'GET',
url: 'https://domain_name.users.io/categories/list',
headers:{'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
withCredentials: true /* to get the Cookie value generated at server-side */
});
==============ON Node Side===============
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization, Access-Control-Allow-Origin, Access-Control-Allow-Headers');
next();
});

Resources