Node.js and Express; POST 404 - ajax

I can't get my server to call a function from the client using node.js and express. I don't need to pass data, I just need to alert to the server that it should call a function. This is what I have (after following numerous tutorials):
client:
$.ajax({
type: 'POST',
url: 'http://localhost:3001/admin',
sucess: function() {
console.log('sucess');
}
server:
var express = require('express');
var app = express();
var server = require('http').Server(app);
app.set('port', process.env.PORT || 3001);
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hjs');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
app.post('/admin', function(req, res) {
console.log("admin refresh");
res.send(200);
});
Error:
POST http://localhost:3001/admin 404 (Not Found)

You have your middleware in the wrong order. Express prossess them in order declared. Move your app.post('/admin... line ABOVE your Not Found middleware.

Related

Req.body from post returns as undefined no matter how I send it

This question has been asked but none of the answers help me figure this out. I'm passing a variable through ajax like so:
var myData = "Hi Og";
$.ajax({
type: 'POST',
data: myData,
url: 'https://example.com:8443',
success: function (data) {
alert(data);
}
});
In my express server I have this in my server.js
var fs = require('fs');
var http = require('http');
var https = require('https');
var bodyParser = require('body-parser')
var privateKey = fs.readFileSync('certificates/key.pem', 'utf8');
var certificate = fs.readFileSync('certificates/cert.pem', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var express = require('express');
var app = express();
app.use( bodyParser.json() ); // to support JSON-encoded bodies
// your express configuration here
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
// For http
httpServer.listen(8080);
// For https
httpsServer.listen(8443);
app.post('/', function (req, res) {
console.log(req.body.myData);
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header('Content-type', 'text/html');
return res.end('<h1>Hello, Secure World!</h1>');
});
With the above code I get a response back at the originating sender with the alert "Hello, Secure World!". However in the console I get "undefined".
I changed the content-type to application/json but that gave me a 500 error. I changed req.body.data and same thing undefined. req.body gives me this = {}
Per #robertklep direction I needed to property parse the body of the data with app.use( bodyParser.urlencoded() );
I incorrectly had this as json which was causing it to be undefined.

AJAX requests to my node server - not getting through

I'm currently redirecting traffic to https on my node server:
var express = require('express');
var path = require('path');
var app = express();
var port = process.env.PORT || 8080;
app.set('port', port);
app.use(express.static(path.join(__dirname, './src/public')));
app.all('*', function(req, res, next) {
if(req.headers["x-forwarded-proto"] === "https"){
// OK, continue
return next();
};
res.redirect('https://'+req.hostname+req.url);
})
app.get('*', function( req, res ) {
res.sendFile(path.join(__dirname, './src/public/index.html'));
} );
app.use(require('./server/routes/index'));
app.listen(process.env.PORT || 8080, function (){
console.log('Express started on port ' + app.get('port') + '; press Ctrl-C to terminate.');
});
module.exports = app;
In doing so, my AJAX calls aren't getting through: net::ERR_CONNECTION_REFUSED. Of course when I remove the above redirect, my AJAX calls make it through.
I managed to find one other post on SO from someone having this issue but the suggestion was to set Access-Control-Allow-Origin to accept any incoming AJAX requests, which seems like a security issue.
If I want continue to use the https redirect, is there a way to allow the AJAX calls through or do I need to turn of the redirect?
Use req.protocal and req.get('host') to get protocol and host url
app.all('*', function(req, res, next) {
if(req.headers["x-forwarded-proto"] === "https"){
// OK, continue
return next();
};
res.redirect(req.protocol + '://' + req.get('host') + req.originalUrl);
})
next accept another callback like
app.all(path, callback [, callback ...])
let you hava a index page then it should like
var index = require('./routes/index');
app.all('*', function(req, res, next) {
if(req.headers["x-forwarded-proto"] === "https"){
// OK, continue
next();
};
res.redirect(req.protocol + '://' + req.get('host') + req.originalUrl);
}, index)

Can't use Express to send data back to client more than once

In my app, I send a post request to the server with data containing a CSV file:
$.ajax({
type:"POST",
contentType: "application/json",
url:"/",
data: JSON.stringify({fileData:My_CSV_FILE}),
success: function(csvJson) {
console.log('in the done block!');
//can use csvJson in this handler
});
});
Note: I'm posting to the home route, and I am able to get a response with the data converted from the server. The problem is that whether I run on localhost or Heroku, I am only able to trigger the POST request once, then I have to restart the server (even if I refresh the page). So I know the issue is with my route somewhere:
UPDATED TO INCLUDE FULL SERVER FILE:
'use strict';
const express = require('express');
const csvtojson = require('csvtojson');
const PORT = process.env.PORT || 3000;
const bodyParser = require('body-parser');
const Converter = require('csvtojson').Converter;
var converter = new Converter({});
let app = express();
app.use(bodyParser.json({limit: '300kb'}));
app.use(express.static(__dirname +'/public'));
app.post('/',function(req,res) {
var csvFile = (req.body.fileData);
converter.fromString(csvFile, function(err, result) {
if(!err) {
console.log(result);
res.json(result);
}else {
res.json({error: 'Could not convert'});
}
})
});
app.listen(PORT, () => {
console.log(`app listening on port ${PORT}`);
});
I'm using Express 4. Again, everything works, but only once. When I run Heroku logs, or check the console on localhost I get:
Error: Can't set headers after they are sent.
But I don't understand how I'm re-setting them.
If wanting to run on localhost, here is a link to the projects github: https://github.com/qctimes/calendar_export
You should move the converter instantiation to be done inside the app.post callback method. This way it will instantiate a new object at every request.
This is is how your code should be:
'use strict';
const express = require('express');
const csvtojson = require('csvtojson');
const PORT = process.env.PORT || 3000;
const bodyParser = require('body-parser');
const Converter = require('csvtojson').Converter;
let app = express();
app.use(bodyParser.json({limit: '300kb'}));
app.use(express.static(__dirname +'/public'));
app.post('/',function(req,res) {
var csvFile = (req.body.fileData);
var converter = new Converter({}); // instantiation is done here
converter.fromString(csvFile, function(err, result) {
if(!err) {
console.log(result);
res.send(result);
}else {
res.send({error: 'Could not convert'});
}
});
});
app.listen(PORT, () => {
console.log(`app listening on port ${PORT}`);
});

Nodejs random query

I'm trying to get a random item from my local database using ajax.The first time i do a ajax request i get a random item afterwards every ajax request return the same item.
var express = require('express')
var app = express();
var customers = require('./module');
var pg = require('pg');
var conString = "postgres://postgres:pass#localhost/test";
var client = new pg.Client(conString);
app.get('/res', function(req, res) {
client.connect(function(err) {
if(err) {
return console.error('could not connect to postgres', err);
}
client.query('SELECT * FROM t_items OFFSET random()*300 LIMIT 1', function(err, result) {
if(err) {
return console.error('error running query', err);
}
console.log(result.rows[0]);
res.contentType('json');
res.send({ some: result.rows[0] });
client.end();
});
});
});
app.set('view engine', 'jade');
app.use(express.static(__dirname + '/public'));
app.set('port', (process.env.PORT || 5000))
app.use(express.static(__dirname + '/public'))
app.get('/',function(req, res){
res.render("index");
});
app.listen(app.get('port'), function() {
console.log("Node app is running at localhost:" + app.get('port'))
})
If I try to wrap it in app.post('/req' )....
i get could not connect to postgres [Error: Connection terminated]
I've tried with client pooling but still the same problem
Just move your query inside function app.get('/res', function(req, res)
This happening because db query is executed only once. To prevent it - move your code inside /res route, and it will be executed every request.

https request semantic issue

I'm trying to make an https request from my node server to my main php server but it looks like the request isn't going through. I'm pretty sure there is an issue with the hostname line as I have read people having random issues with it but it could be something else. The php server is secured with ssl and is an amazon ec2.
exports.authenticate = function(request, callback) {
var https = require('https');
var options = {
hostname: 'https://mysite.com',
port: 443,
path: '/ajaxim/auth.php',
method: 'GET',
cookie: exports.cookie + '=' + request.sessionID
};
var req = https.request(options)
req.end();
req.on('response', function (response) {
var data = '';
response.setEncoding('utf8');
response.on('data', function(chunk) {
data += chunk;
});
//console.log (request.sessionID);
response.on('end', function() {
try {
callback(JSON.parse(data));
} catch(e) {
callback();
}
});
});
};
Any suggestions will be insanely helpful. I'm just trying to get hint of the right direction.

Resources