How to perform PUT in Node JS - node.js

Below is my app.js code.
import bodyParser from 'body-parser';
import cors from 'cors';
import requestIp from 'request-ip';
import os from 'os';
import { AppRoutes, AuthRoutes } from './routes';
const app = express();
app.use(cors());
app.disable('x-powered-by');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use((req, res, next)=> {
const clientIp = requestIp.getClientIp(req);
logger.debug(JSON.stringify(req.socket.address()));
logger.debug(`incoming IP ${clientIp}`);
next();
});
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();
});
// Api Routes.
app.use('/api/login', AppRoutes);
app.use('/api', verifyToken, AuthRoutes);
export default app;
Below is my index.js code. Below code is working fine for GET and POST but its not working for PUT. Its giving an error.
You don't have permission to access /api/save-user-profile/{user-name}.
import {
getCustomersbyId
} from './controller/customer-controller';
import { Login } from './controller/login';
import {
modelEdit,
saveProfile
} from './controller/extension';
const AuthRoutes = Router();
const AppRoutes = Router();
AuthRoutes.get('/customers/', getCustomersbyId);
AuthRoutes.post('/model-entity-links/info', modelEdit);
AuthRoutes.put('/save-user-profile/:username', saveProfile);
AppRoutes.post('/', Login);
export { AuthRoutes, AppRoutes };
When I am changing PUT to POST it is working fine. But I want to do it using PUT. Am I missing here anything to configure PUT.
I have tried below code as well in app.js. But still getting same issue.
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');
My saveProile code is as below.
export const saveUserProfile = (req, res) => {
logger.debug({ method: 'saveUserProfile', message: MESSAGE.ENTER });
const { username } = req.params;
const userProfileInfo = JSON.parse(JSON.stringify(req.body));
if (username && !isEmptyObject(userProfileInfo)) {
postUserProfile(username, userProfileInfo)
.then(r=>{
res.status(200).send(r.data);
})
.catch(e=>{
logger.error({ method: 'saveUserProfile', message: e.response ? JSON.stringify(e.response.data.response_message) : e });
parseError(e, res);
});
} else {
logger.error({ method: 'saveUserProfile', message: MESSAGE.ERROR_INVALID_PARAM });
parseError(MESSAGE.ERROR_INVALID_PARAM, res, true);
}
};

I have resolved this issue. It was an apache server issue where PUT and DELETE operation was restricted. We have made changes in apache configuration and it worked. Thank you all for responses.

Related

has been blocked by CORS policy: Request header field contend-type is not allowed by Access-Control-Allow-Headers

I learn NodeJS and REACT and I built the frontend and the backend.
for now, I want to connect the front to the back.
so, I add those lines of code in my app.js of the backend:
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE");
next();
});
and my full app.js (pay attention that I delete the URL of the MongoDB because i don't want to publish it:
const express = require("express");
const bodyParser = require("body-parser");
const mongoose = require("mongoose");
const placesRoutes = require("./routes/places-routes");
const usersRoutes = require("./routes/users-routes");
const HttpError = require("./models/http-error");
const app = express();
//Parse any incoming request body and extract any json data that is in there converted to regular javascript data structure (object,array...) and than call next autometically to reach the next middleware inline
app.use(bodyParser.json());
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
);
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PATCH, DELETE");
next();
});
app.use("/api/places/", placesRoutes); //place route
app.use("/api/users/", usersRoutes); //user route
//run only if the other routes did not send a respond
app.use((req, res, next) => {
const error = new HttpError("Could not find this route.", 404);
throw error;
});
app.use((error, req, res, next) => {
//this function will execute if any middleware Infront of it yields an error
if (res.headerSent) {
//check if respond already has been sent
return next(error);
}
//if code properties is set or default 500 => error code that something went wrong
res.status(error.code || 500);
res.json({ message: error.message || "An unknown error occurred!" });
});
mongoose
.connect(
"something"
)
.then(() => {
app.listen(5000);
console.log("connected");
})
.catch((err) => {
console.log(err);
});
and my error:
Full description of the error if you can't see the image:
Access to fetch at 'http://localhost:5000/api/users/signup' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field contend-type is not allowed by Access-Control-Allow-Headers in preflight response.
POST http://localhost:5000/api/users/signup net::ERR_FAILED
TypeError: Failed to fetchat authSubmitHandler (Auth.js:74:1)at HTMLUnknownElement.callCallback (react-dom.development.js:189:1)at Object.invokeGuardedCallbackDev (react-dom.development.js:238:1)at invokeGuardedCallback (react-dom.development.js:291:1)at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:306:1)at executeDispatch (react-dom.development.js:391:1)at executeDispatchesInOrder (react-dom.development.js:416:1)at executeDispatchesAndRelease (react-dom.development.js:3300:1)at executeDispatchesAndReleaseTopLevel (react-dom.development.js:3309:1)at forEachAccumulated (react-dom.development.js:3281:1)at runEventsInBatch (react-dom.development.js:3326:1)at runExtractedPluginEventsInBatch (react-dom.development.js:3536:1)at handleTopLevel (react-dom.development.js:3580:1)at batchedEventUpdates$1 (react-dom.development.js:21726:1)at batchedEventUpdates (react-dom.development.js:798:1)at dispatchEventForLegacyPluginEventSystem (react-dom.development.js:3590:1)at attemptToDispatchEvent (react-dom.development.js:4310:1)at dispatchEvent (react-dom.development.js:4231:1)at unstable_runWithPriority (scheduler.development.js:656:1)at runWithPriority$1 (react-dom.development.js:11076:1)at discreteUpdates$1 (react-dom.development.js:21743:1)at discreteUpdates (react-dom.development.js:811:1)at dispatchDiscreteEvent (react-dom.development.js:4210:1)

Backend Node routes not working after heroku deployment

I have recently deployed my node.js backend using Heroku but now it seems like my routes don't work anymore. It always goes through my error route to return "Could not find this route." This did not happen when I was using localhost whilst developing.
app.js:
const express = require('express');
const bodyParser = require('body-parser');
const HttpError = require('./models/httpError');
const questionRoutes = require('./routes/questionRoutes');
const app = express();
app.use(bodyParser.json());
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept, Authorization'
);
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE');
next();
});
app.use('/api/questions', questionRoutes);
app.use((req, res, next) => {
console.log(req.url);
const error = new HttpError('Could not find this route.', 404);
throw error;
});
app.use((error, req, res, next) => {
if (res.headerSent) {
return next(error);
}
res.status(error.code || 500);
res.json({ message: error.message || 'An unknown error occurred!' });
});
app.listen(process.env.PORT || 5000);
I am not using any environment variables. Here is the heroku link to my backend: https://mealoftheday.herokuapp.com/
Any help would be appreciated!
router.get('*', (request, response) => {
response.sendFile(path.join(__dirname, 'etsa2/build', 'index.html'));
});
Add this file to your routes my issue was solved hope yours too get solved

Angular route is not working in Combined MEAN?

I created a single page app using Angular.I'm using Node/Express on the back-end. While Express is serving my static index.html correctly.
When i try to navigation to some angular route from url address bar it saying cannot get /login...
i found this question on stackoverflow it is exactly what i am saying but its not answered yet.
Angular - Routing is not working (MEAN)
Here is my code.
var path = require("path");
var express = require("express");
var mongoose = require("mongoose");
var app = express();
require('./startups/prod')(app);
// Temp.
const TempRoutes = require("./routes/temp");
mongoose.connect('mongodb://localhost:27017/node-angular', { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => {
console.log("Connected to database.");
})
.catch(() => {
console.log("Connection Failed.");
});
app.use(express.json());
app.use("/", express.static(path.join(__dirname, "dist")));
app.use((request, response, next) => {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader(
"Access-Control-Allow-Headers",
"Origin, X-Requesed-With, Content-Type, Accept,Accept-Language,Content-Language, Authorization");
response.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, PATCH, PUT, DELETE, OPTIONS");
next();
});
app.use((request, response, next) => {
response.sendFile(__dirname, path.join("dist", "index.html"))
})
module.exports = app;

Cors not working in express even when I user npm package [duplicate]

This question already has answers here:
Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?
(36 answers)
Closed 3 years ago.
I have been trying to get cors to working for the past 24 hours but it doesnt work. I have tried using the npm package cors in the app variable app.use(cors()) and also in a specific route e.g router.post('/', cors(),(req, res) => { ... } and also using the longer way of using app.use , my code is below.
mailer.js [Route]
const express = require('express')
const nodemailer = require('nodemailer')
var mailerTransport = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
auth: {
user: 'user#gmail.com',
pass: 'password'
}
})
const router = express.Router()
router.post('/',(req, res) => {
const mailOptions = {
from: 'email#gmail.com', // sender address
to: 'email2#gmail.com', // list of receivers
subject: req.body.subject, // Subject line
html: `email sent`// plain text body
};
mailerTransport.sendMail(mailOptions, function (err, info) {
if(err)
{
...
}
else
{
...
}
});
})
module.exports = router;
server.js
app.use(bodyParser.json())
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "*")
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
app.options('*', (req, res) => {
// allowed XHR methods
res.header('Access-Control-Allow-Methods', 'GET, PATCH, PUT, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
res.send();
});
next()
})
app.use("/mailer", mailer)
First install npm install cors for your node application. and make following changes in server.js
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
First you have to install npm package for cors as "npm install cors --save".
In app.js file declare "var cors = require("cors");"
and after that use "app.use(cors());".
I think its work for you.

React Express Fetch Post CORS error: Response to preflight request doesn't pass access control check: It does not have HTTP ok status

I'm trying to set up a basic user signup form with React, Node, and Express, and using fetch. However, I'm getting the following errors in the Chrome console when I try and send a post request:
1) "OPTIONS http://localhost:7001/v1/register 500 (Internal Server Error)"
2) "Access to fetch at 'http://localhost:7001/v1/register' from origin 'http://localhost:3001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status."
My eventual goal is to save the user's email and password in a database, but for now all I want is for the request to go through to the backend and have the backend log the body to make sure everything works. I've tried several different ways of setting headers, and I have no idea what's wrong. Below is the code.
Frontend form submit function:
handleSubmit(e) {
e.preventDefault();
const signUpInfo = this.state; // { email: 'test#gmail.com', password: '123' }
console.log(signUpInfo);
fetch('http://localhost:7001/v1/register', {
method: 'POST',
body: JSON.stringify(signUpInfo),
headers: {
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(response => console.log('Success:', response))
.catch(error => console.error('Error:', error));
}
server.js
const express = require('express');
const compression = require('compression');
const cfg = require('config');
const path = require('path');
const logger = require('morgan');
const cookieParser = require('cookie-parser')
const bodyParser = require('body-parser');
const config = require('config');
const app = express();
app.use(compression());
app.use(bodyParser());
app.use(cookieParser());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.static(path.join(__dirname, 'public')));
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,DELETE");
res.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Access-Control-Allow-Headers, Content-Type, Authorization, Origin, Accept");
res.setHeader('Access-Control-Allow-Credentials', true)
next();
});
// CONTROLLERS
const userController = require('./controllers/userController.js');
// ROUTES
app.post('/v1/register', userController.register);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
app.listen('7001', function() {
console.log('API server listening on port 7001!');
});
module.exports = app;
userController.js
exports.register = async (req, res, next) => {
try {
console.log(req.body);
res.status(200).json({ status: 200, data: req.body, message: "test" });
} catch (err) {
console.log(err);
res.status(500).json({ status: 500, data: null, message: err });
}
}
All I'm looking for is for the backend console to print out the body. It works with axios and $.ajax, but not with fetch. I've also tried using a proxy server to no avail (and would like to get it to work without a proxy).
Not sure if this is relevant, but I'm using Chrome as the browser and Sequelize.
Any help would be greatly appreciated. I feel like I'm missing something fundamental. Any helpful articles to deepen my learning would be a plus!
Instead of using
const app= express();
try to use
const app=express().use('*', cors());
and remove
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,DELETE");
res.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Access-Control-Allow-Headers, Content-Type, Authorization, Origin, Accept");
res.setHeader('Access-Control-Allow-Credentials', true)
next();
});
see if this works.
First Install "cors":
npm i cors
Second import "cors":
cors = reqquire("cors");
Third use "cors":
const app = express();
app.use("*", cors());

Resources