How do I use express.json() and set headers (res.setHeader) simultaneously? - json

I am trying to view the body of a POST request and also set some headers. Specifically, I need to allow localhost -> localhost communication, which means adding Access-Control-Allow-Origin: * as a header.
My code so far is:
const express = require("express");
const app = express();
const port = 8080;
app.use(express.json());
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
res.sendStatus(200);
next();
});
app.post('/', function (req, res) {
console.log(req.body.name)
res.end();
});
app.listen(port, () => console.log(`Listening on port ${port}`));
When I run the server I get Cannot set headers after they are sent to the client.
How can I combine both app.use()s?
I've tried changing the order of the calls but that doesn't work.

I figured out a way after I posted the question, so I'm sharing it here for anyone else:
const express = require("express");
const app = express();
const port = 8080;
app.use(function( req, res, next ) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Content-Type"
);
res.sendStatus(200);
let data = "";
req.on("data", function( chunk ) {
data += chunk;
console.log(data);
next();
});
});
app.listen(port, () => console.log(`Listening on port ${port}`));

Related

Why Does My req.body Return Empty on Express

I can't understand why I'm getting an empty req.body {} in client side I get undefined or when I try to use payload = req.body.payload and console.log(payload) I get undefined on the server side and on the client side I get (chrome developer tool console)
ERROR TypeError: Cannot read properties of null (reading 'payload').
What I don't understand is the server receives the request payload(status 201) the response payload is empty, also correct me if I'm wrong the response is a JavaScript object and in the service the original payload is contained so shouldn't I get that in the response.
I have looked at many topics that have the same issue. I'm already doing things that fixed some of the issues.
I have a Content-Type application/json, I apply the app.use(json()) before I use my routes, which seemed to have been the problem with some. Yet I still get empty re.body. I have tried so many things with no luck. Am I missing something? Code snippet.
I would appreciate a point in the right direction
Thanks In Advance
PH.
service.ts
export interface Products{
_id: string,
name: string
}
#Injectable({
providedIn: 'root'
})
export class SearchService {
constructor(private http:HttpClient) { }
searchProducts(query:string){
console.log("Does it get my searchProducts");
return this.http.post<{payload: Array<Products>}>(productsUrl, {payload: query}, {
headers: new HttpHeaders({'Content-Type': 'application.json'})
}).pipe(
map(data => data.payload)
);
}
}
header.ts
sendData(event:any){
//console.log(event.target.value);
let query:string = event.target.value;
//Will match if query is nothing or only spaces
let matchSpaces:any=query.match(/\s*/);
console.log("What about match");
if(matchSpaces[0] === query){
console.log("What about query");
//.products=[];
console.log("what is in collection", this.products);
this.hasQuery = false;
return;
}
console.log("about to call service")
this.searchService.searchProducts(query.trim()).subscribe((results) =>{
console.log("does it get pass subscribe")
// this.products = results;
this.hasQuery = true;
console.log(results);
})
}
route file getProducts.js
var express = require('express');
const cors = require('cors');
var bodyParser = require('body-parser')
const Products = require('../../../liveSearch');
const { query } = require('express');
var router = express.Router();
const app = express();
router.get('/', function(req, res){
res.send('GET route on api here.');
});
/*router.post('/getproducts', function(req,res){
res.send("Trying to post")
});*/
/*app.use(cors());
var corsOptions = {
origin: 'http://localhost:4200',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}*/
router.post('/getProducts', async(req, res) =>{
let payload=req.body;
//let payload= req.body.payload;
let search = await Products.find({name: {$regex: new RegExp('^'+payload+'.*',
'i')}}).exec();
//Limit search to 10
search = search.slice(0, 10);
console.log("Payload", payload)
//.log("Inside search",search);
res.status(201).json(payload) //added to see why I couldn't get
response
// res.send({payload:search});
})
server.js
const express = require('express');
const cors = require('cors');
const router = express.Router();
var bodyParser = require('body-parser');
const Products = require('./liveSearch');
const getProducts = require('.../../controllers/api/getProducts/getProducts')
//const products = require('.../../routes/products.js')
const mongoose = require('mongoose');
//mongoose.Promise = Promise;
mongoose.connect('mongodb://localhost/productLiveSearch', {useNewUrlParser:
true, useUnifiedTopology: true, });
const db = mongoose.connection;
db.on('error', error => console.log(error));
db.once('open', () =>{ console.log('Connected to Mongoose')});
const app = express();
app.use(function(req,res,next){
res.header('Access-Control-Allow-Origin', '*');
res.header('content-type','application/json');
res.header('Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Methods','POST, GET, DELETE, PUT, OPTIONS');
res.header('Allow', 'GET, POST, OPTIONS, PUT, DELETE');
next();
});
app.use(cors());
var corsOptions = {
origin: 'http://localhost:4200',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
app.use(express.json());
app.use(express.urlencoded({extended:true}));
// app.use(express.json({ limit: "1000mb" }));
// app.use(express.urlencoded({ limit: "1000mb", extended: true }));
app.use('/', getProducts);
app.use('/getProducts', getProducts);
app.get('/', function(req, res){
res.send('hello world');
});
app.listen(process.env.Port|| 3000, () => {
console.log("Server has started on Port 3000");
});

How to add a users auth in feathers middleware?

I use feathersjs framework in my projekt. In older version my middleware it was work but afer update a framework and after created new app with authenticate a middleware not working.
My index.js file show like below:
const cookieParser = require('cookie-parser');
const { authenticate } = require('#feathersjs/express');
module.exports = function (app) {
app.get('/login', (req, res) => {
res.sender('login');
});
app.use('/', cookieParser(), authenticate('jwt'), async (req, res) => {
const { user } = req;
try {
await app.service('users').get(user._id);
res.sender('home');
} catch(e){
res.redirect('/login');
}
});
}
I have a login script in jQuery like below:
$(document).ready(function(){
const socket = io();
const app = feathers();
app.configure(feathers.socketio(socket));
app.configure(feathers.authentication({
storage: window.localStorage
}));
$('.form-signin').submit(function(){
app.authenticate({
strategy: 'local',
username: $('#inputUsername').val(),
password: $('#inputPassword').val(),
}).then( result => {
document.cookie = "feathers-jwt=" + result.accessToken;
window.location.href = "/";
}).catch(error => {});
});
});
My problem is when I click a login button with a data correctly I receive an accessToken but I can't see home page and app show me every time 401 error code - not authorization with.
An console shows me this info: info: Invalid authentication information (no `strategy` set) {"type":"FeathersError","name":"NotAuthenticated","code":401,"className":"not-authenticated","errors":{}}
In new version not working too failureRedirect: '/login'
SOLUTION
Add below code before app.get('/', authenticate('jwt'), (req, res) => {});
app.use('/', cookieParser(), (req, res, next) => {
var cookies = req.cookies;
var token = cookies['feathers-jwt'];
req.authentication = {
strategy: 'jwt',
accessToken: token
}
next();
})

Express POST Request Appears Undefined in MySQL Database

When I submit form data from HTML form, all values added to MySQL database appear as Undefined. I console.logged req.body and it is shown correctly.
The HTML form in client is a normal form (Important to say that I don't send multipart/form-data, no "enctype" attribute in HTML). I've been looking all over the internet to figure it out what am I doing wrong. I'd like to know what is the problem.
Here's my backend code:
const express = require('express');
const bodyParser = require('body-parser'); // Required for POST requests to work
const mysql = require('mysql');
const path = require('path');
const cors = require('cors');
const app = express();
const port = 1000;
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.use(cors());
const DB = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '1',
database: 'onlineshop',
});
DB.connect(err => {
if (err) throw err
console.log("Connected to MySQL database")
});
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.post('/register', (req, res) => {
let newCustomer = req.body;
let q = `INSERT INTO customers (firstname, lastname, email, password, city, street, role)
VALUES ("${newCustomer.firstname}",
"${newCustomer.lastname}",
"${newCustomer.email}",
"${newCustomer.password}",
"${newCustomer.city}",
"${newCustomer.address}",
0`
const result = DB.query(q, (err,result)=>{
if (err) throw err
res.json(result)
})
});
app.listen(port, console.log('App listening at port 1000'));
Thank you!
Is your POST from an HTML form?
If so you need the urlencoded body parser, and you only have the json one. The payload for POSTs from HTML forms is in the urlencoded format. (You can see it in the Network tab of devtools if you're curious.)
const bodyParser = require( 'body-parser' )
app.use( bodyParser.json() )
app.use( bodyParser.urlencoded( { extended: true } ) ) /* add this line */

Keep getting CANNOT POST /login everytime i login

I got the codes from a tutorial, seems to work fine until I made routers since I'm trying to create an E-commerce website with a login system.
This is my index.js code
const express = require('express');
const app = express();
const prodRouter = require('./server/routes/prodRouter');
const loginRouter = require('./server/routes/loginRouter');
const regRouter = require('./server/routes/regRouter');
const contRouter = require('./server/routes/contRouter');
const checkRouter = require('./server/routes/checkRouter');
const profRouter = require('./server/routes/profRouter');
const path = require('path'); const port = 3500;
app.use(express.static('public'));
app.set('views', path.join(__dirname, 'server/views'));
app.set('viewengine', 'pug');
app.use('/prod', prodRouter);
app.use('/login',loginRouter);
app.use('/reg', regRouter);
app.use('/cont',contRouter);
app.use('/check', checkRouter);
app.use('/profile',profRouter);
app.get('/', (req, res) =>{res.render('Home.pug', {}); });
app.listen(port, (err) => { // arrow function feature from ES6 if(err){ console.log(err); }
console.log(`Listening to port ${port}!`); });
and loginRouter.js
const express = require('express'); const router = express.Router();
const app = express();
const mysql = require('mysql');
const server = require('http').createServer(app);
bodyParser = require('body-parser');
const connection = mysql.createConnection({
host: 'localhost',
database: 'login',
user: 'root',
password: '',
});
users = []; connections = [];
router.get('/', (req, res) => {
res.render('login', {});
});
app.use(bodyParser.urlencoded({
extended: true
});
app.use(bodyParser.json());
connection.connect();
app.post('/', function(req, res){
var email= req.body.email;
var password = req.body.password;
connection.query('SELECT * FROM user WHERE email = ?',[email],function (error, results, fields) {
if (error) {
// console.log("error ocurred",error);
res.send({
"code":400,
"failed":"error ocurred"
})
}else{
// console.log('The solution is: ', results);
if(results.length >0){
if([0].password == password){
return res.redirect('/profile');
}else{
res.send({
"code":204,
"success":"Email and password does not match"
});
}
}else{
res.send({
"code":204,
"success":"Email does not exits"
});
}
}
});
enter code here
});
module.exports = router;
my pug form:
form#login-form(method='post')
fieldset.input
p#login-form-username
label(for='modlgn_username') Email
input#modlgn_username.inputbox(type='text', name='email', size='18', required)
p#login-form-password
label(for='modlgn_passwd') Password
input#modlgn_passwd.inputbox(type='text', name='password', size='18', required)
.remember
p#login-form-remember
label(for='modlgn_remember')
a(href='#') Forget Your Password ?
input.button(type='submit', value='Sign In')
I'm pretty sure I did something wrong with the router, because every time I login, I keep getting CANNOT POST instead of going to the profile page.
Any help would be greatly appreciated.
EDIT: I added my pug code for form.
EDIT: the problem only occurs if the login page is not the main page.
example:
login page > *logs in > profile - no problem
home page > login page > *logs in > profile - error
This is happening because you don't have an action on your form (see this article for details). When you don't have an action the form is submitted to the URL it lives at, so if you POST on your home page without an action the post will go to /home.
Change the form element to look like this:
form#login-form(method='post' action='/login')

Node.js Express.js not always sending valid json

Here is the express code
app.post('/v1/sessions' function(req,res){
res.send({id:1234});
});
For some reason the json response comes back like this
OK{ id: 1234}
Why is the OK there?
EDIT
Ok so here is all of my code. I don't see where it would be sending the OK.
var express = require('express');
var app = express();
app.enable('trust proxy');
app.use(express.bodyParser());
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
app.post('/v1/sessions', function(req, res) {
if(req.body.email == 'testuser#captusr.com' && req.body.password == 'testpass'){
res.send(200, JSON.stringify({token:{id:'longstring',email:'testuser#captusr.com'}}));
} else {
res.send({code:403, error:"Invalid email or password"});
}
});
app.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'HEAD, GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, X-Requested-With, Origin, Accept');
res.header('Access-Control-Allow-Credentials', 'true');
if (req.method.toLowerCase() === 'options') {
res.send(200);
} else {
next();
}
});
app.listen(3000);
console.log('Listening on port 3000');
Can you replace this line:
res.send(200, JSON.stringify({token:{id:'longstring',email:'testuser#captusr.com'}}));
with this and see if that solves it. Express does the 200 and JSON.stringify for you, so don't re-do it.
res.send({token:{id:'longstring',email:'testuser#captusr.com'}});