Cannot fetch from localhost with Authorization header - reactjs

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

Related

Fetch http://localhost:3001/ from Chrome Extension with React

I have seen some similar problems and solutions where people want to hit http://localhost:3001/some_url and use cors to do so.
But my problem is a little different. My web app is not a website but a web-extension.
SO far I cannot find a way to fetch from http://localhost:3001/url even with using cors.
What I have tried is:
Server:
const cors = require("cors");
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();
});
app.use(
cors({
origin: "http://localhost:3001/url" // restrict calls to those this address
})
);
In background.js file:
create(urls){
console.log(urls);
return new Promise((resolve, reject) =>{
fetch('https://cors-anywhere.herokuapp.com/'+'http://localhost:3001/url', {
method: 'POST',
body: JSON.stringify(urls),
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
"Access-Control-Allow-Origin: *"
}
})
.then(result => result.json())
.then(json => resolve(json))
.catch(err => {
console.log(err);
reject(err);
});
});
}
I have also added "proxy": "http://localhost:3001/url" in packages.json.
I am still getting the error:
Access to fetch at 'http://localhost:3001/url' from origin 'chrome-extension://extension_id' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:3001/url' that is not equal to the supplied origin. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Is there any way to solve the issue?
It looks like you're adding a path /url to the origin, but an origin is:
Web content's origin is defined by the scheme (protocol), host
(domain), and port of the URL used to access it
Try using http://localhost:3001 as the origin value.

Api call cause error 'Access-Control-Allow-Origin' header is present on the requested resource

I am trying to call an api but it is giving me following error :
Access to fetch at 'https://someapi.url/profile?FullName=sadaf&DateFrom=2000-01-01' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I am using react and the code is :
try {
let url = `https://someapi.url/profile?FullName=sadaf&DateFrom=2000-01-01`;
let response = await fetch(url,{
mode: 'cors', // no-cors,
credentials: 'include',
headers: {
'Content-Type': 'application/json',
"Accept": 'application/json',
'Origin' : 'http://localhost:3000'
//'Content-Type': 'text/xml'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
});
this.setState(() => {
return {
searchResults : response
}
})
} catch (error) {
console.error(error);
}
please guide what to do
The error is due to CORS, there is nothing wrong with the front-end code.
Cross-Origin Resource Sharing (CORS) is a mechanism that uses
additional HTTP headers to tell browsers to give a web application
running at one origin, access to selected resources from a different
origin.
To fix this issue, the server should set the CORS headers,
See here on how to enable CORS for your server
If your server is running express you need to set cors like this,
app.use(function(req, res, next) {
// update to match the domain you will make the request from
res.header("Access-Control-Allow-Origin", "YOUR-DOMAIN.TLD");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
or use the cors middleware for express

How to send both data and header to a server?

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.

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

AngularJs $http GET passing custom header returns 404

I've been reading many blogs about it and I could not figure it out how to solve my problem..
I need to pass a token as a custom header to a get $http.. I get an error 404 because the GET request turns into OPTIONS.
The nodejs API Rest is working properly as I test it with the chrome "rest console" app.
Thank you Kasper..
This was my server code before starting this thread..
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", 'X-Requested-With, Content-Type');
res.header('Access-Control-Allow-Methods', 'GET, POST', 'DELETE', 'PUT');
next();
});
With this server code, everytime I send a request (GET) from the client with AngularJS adding a custom header "token"
myapp.factory("Booking", function ($resource) {
return $resource(
serverUrl + "/agp/pricelist",
{}, //default parameters
{
"reviews": {'method': 'GET', 'params': {'reviews_only': "true"}, isArray: true,
headers: {'Content-Type':'application/json', 'token': 'diego' }}
}
);
});
So, when you send a custom header rather than the followings:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type, but only if the value is one of:
application/x-www-form-urlencoded
multipart/form-data
text/plain
the type cors request is not "simple" anymore with a custom header, so when the client makes the request in fact it is making a pre-request with method "OPTIONS" first and then makes the "GET".. in between I was getting 404 error.
I added then to my server:
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", 'X-Requested-With, Content-Type, token');
res.header('Access-Control-Allow-Methods', 'GET, POST', 'DELETE', 'PUT', 'OPTIONS');
res.header('Access-Control-Request-Method', 'GET');
res.header('Access-Control-Request-Headers', 'token');
if ('OPTIONS' == req.method) {
res.send(200);
}
else {
next();
}
// next();
});
It was supposed to work with the access-control headers I added, but it was still sending back the 404 error.. So the work around was to add
if ('OPTIONS' == req.method) {
res.send(200);
}
else {
next();
}
Because as I said before, with a custom header the client first ask for permissions with OPTIONS method, and the sends the proper GET or whatever.
I did not find out another solution since this seems to be a work around, but at least I am not stuck anymore.
This is a good and practical link a about CORS
http://www.html5rocks.com/en/tutorials/cors/
Hope this helps someone.
King regards
I'm not too versed with CSRF and the likes, but I do believe this might be the issue I had with contacting my Express server with Angular.
http://mircozeiss.com/using-csrf-with-express-and-angular/
As stated in that article, Angular uses it's own X-XSRF-TOKEN for CSRF protection. Hence, you need to take that into account when setting up your server.
Following along with that guide and Express v3 all my requests going from the client side to the server side, magically started working.
If this is not the case (and I'm way out there), let me know.
What does your full serverside config look like?

Resources