Issue with PUT request in node js - node.js

I have below code which is working fine for GET and POST but not for PUT in node js. I am using method overloading for GET and PUT.
const AuthRoutes = Router();
const AppRoutes = Router();
AuthRoutes.get('/customer/:customername', getCustomerbyname);
AuthRoutes.post('/calculate/:id', calculate);
AuthRoutes.put('/customer/:customername', saveCustomer);```
Here my GET and POST is working fine but for PUT its giving me error. Below URL I am trying for PUT.
https://domainname/customer/abc
I dont know what I am missing here.
Error - You don't have permission to access /domainname/customer/abc
Can you please help me if I am missing something here. Basically I am trying to do a PUT request by providing customer name in URL and other details in BODY section of request. So if customer with name exist, it will update it otherwise create it newly. Am I missing any npm package here?

Try this:
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");
res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
next();
});
I took it from here :
Response

Related

CORS Issue: Unable to send post request using NodeJs and Angular

I am getting this message when trying to send a post request:
Access to XMLHttpRequest at 'http://localhost:3002/api/products/checkout' from origin
'http://localhost:4200' has been blocked by CORS policy: Request header field content-type
is not allowed by Access-Control-Allow-Headers in preflight response.
Right now I'm simply trying to send data to my backend and then log it in the console. Get requests work fine but for some reason I get that CORS error when trying post. Here is my code:
Angular code:
//api call
return this.http.post('http://localhost:3000/api/checkout', cart)
NodeJs code:
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader(
'Access-Control-Allow-Header',
'Origin, X-Requested-With, Content-Type, Accept');
res.setHeader(
'Access-Control-Allow-Methods',
'GET, POST, PATCH, DELETE, OPTIONS');
next();
})
app.post("/api/checkout", (req, res, next) => {
const cart = req.body;
console.log(cart)
res.status(201).json()
})
module.exports = app;
In the network calls I can see that Request Headers is:
Access-Control-Request-Headers: content-type
while Response Headers is:
Access-Control-Request-Headers: Origin, X-Requested-With, Content-Type, Accept
I'm not sure if content-type being lower case has anything to do with the issue.
You should use req.set instead, just change setHeader to set only. Here is the document https://expressjs.com/en/api.html#res.set
And if you just using localhost, there's another easier option, you can use proxy. More information can be found here https://angular.io/guide/build#proxying-to-a-backend-server
I think the problem that you wrote Access-Control-Allow-Header instead of Access-Control-Allow-Headers, but I cannot test it now.
Be aware that you need to serve OPTIONS requests too. Which is just responding with an empty message body using the same headers. You can get these kind of OPTIONS requests before PUT, PATCH, DELETE from certain HTTP clients e.g. from browsers too.

No 'Access-Control-Allow-Origin' header is present on the requested resource NodeJS API

I am using a Angular 2 app and a NodeJS API. When I had the API in localhost everything was working just right, but I published my NodeJS API to a real server and it gives me that error when I try to access to any method of the API:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource
I was checking some anwsers from another topics here in stackoverflow and nothing has worked for me.
I've this snipped :
app.use(require("cors")());
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept,responseType"
);
res.setHeader(
"Access-Control-Allow-Methods",
"POST, GET, PATCH, DELETE, OPTIONS"
);
next();
});
So I have the "*" in Access-Control-Allow-Origin header why I got the error that I don't have this header in my headers?
Thanks in advance.
Use only the middleware
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
more details

ExpressJS Different Domain Name - CORS

I am having a challange currently setting the domain for a cookie I am sending with the response from my expressjs implementation but currently it is only setting the IP address of where my expressjs server is at(the end point).
Here is my initial CORS configuration;
router.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With,
Content-Type, Accept, pwd, email");
next();
});
Here is my res.cookie line inside my authentication part;
res.cookie('token', token, {domain: "localhost", expires: new
Date(Date.now() + 600000*100000), httpOnly: true});
When I log in using chrome, very oddly I get the cookie but under the IP address of my expressjs endpoint, lets say "http://88.13.91.0" so when I refresh I lose it. I also dont see in the response for the expressjs api the "set-cookie" header in the response, but I do get the cookie. I have cleared the cookie to make sure its coming after attempting to log in so I know its not stale. I also have in my fetch call "credentials" set to "include" as documented but no luck.
My question is, am I not able to set the domain if its not the same as the endpoint? My thought is that maybe this is a security issue and as a result blocked because no one should be able to set a cookie for a domain that isn't theres, or maybe I am wrong.
Try CORS like this and
import * as cors from "cors";
// or
const cors = require ('cors');
app.get("/", function (req, res) {
res.setHeader("Content-Type", "application/x-www-form-urlencoded");
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
res.setHeader("Access-Control-Allow-Credentials", true);
add this above all your middleware
app.use(cors());

CORS request not working when sending authorization headers

EDIT: Kevin B answered my question in a comment below. I added some logic to send a 200 request if an OPTIONS http request hit my API to fix the problem. Here is the code:
var allowCrossDomain = function(req, res, next) {
if ('OPTIONS' == req.method) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,PATCH,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
res.send(200);
}
else {
next();
}
};
router.use(allowCrossDomain);
Original Question:
I currently am trying to get an Ionic 2 application running on my localhost to be able to send data to an Express 4 application. It works when I send requests without an authorization header. However, once I added auth headers, my API began to throw errors. I have done my research and have tried to implement what I found here: (https://stackoverflow.com/a/15254158/5379931.
However, I am getting errors still. If I set Access-Control-Allow-Origin like this:
res.header("Access-Control-Allow-Origin", "http://localhost:8100");
I get this error:
XMLHttpRequest cannot load URL. Response to preflight request doesn't pass
access control check: The 'Access-Control-Allow-Origin' header has a value
'http://localhost:8100/' that is not equal to the supplied origin. Origin
'http://localhost:8100' is therefore not allowed access.
If I set my Access-Control-Allow-Origin header like this:
res.header("Access-Control-Allow-Origin", "http://localhost:8100/");
I get this error:
XMLHttpRequest cannot load URL. 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 400.
Here is the rest of my express 4 code that is relevant:
router.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "http://localhost:8100");
res.header("Access-Control-Allow-Headers", "Origin, Authorization, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Allow-Credentials", true);
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
next();
});
It looks like you forgot to respond to the options request. By not responding, it will go to your error handler and be dealt with as if it were an error.
Just send a 200 status within your .use if it is an options request so that it doesn't reach your error handler.

CORS in Node.js and AngularJS

I have a CORS problem with my app.
My stack is Node.js with Express 4 and AngularJS using Restangular
I already have tried a few things (for example) but I keep getting:
XMLHttpRequest cannot load http://localhost:8080/api/users. Request header field Content-Type is not allowed by Access-Control-Allow-Headers.
In the server side I have this headers:
app.all('/*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods", "GET, POST","PUT");
next();
});
In the AngularJS part I am using this:
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
And I am doing the post with Restangular like this:
var baseUsers = Restangular.all('users');
....
....
baseUsers.post(newUser).then(function(user){
console.log(user);
});
One more thing, in the Node.js server I am consoling the req.method and it says OPTIONS, I really don't know why.
Perhaps is something silly, hope someone can help me.
Thanks!
Change -
res.header("Access-Control-Allow-Headers", "X-Requested-With");
TO
res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
Source 1
Source 2
I am posting same answer with a detailed code, Because i got some issues when i use the selected answer.
Just pull the code below after initialization of the app object
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","PUT");
next();
});
I hope this will be little bit more helpful.

Resources