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)
Related
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}`);
});
taking straight from this post:
This code never executes.
var Promise = require("bluebird");
Promise.promisifyAll(require("restify"));
var restify = require("restify");
var http = require('http');
const PORT=7070;
function handleRequest(request, response){
response.end('It Works!! Path Hit: ' + request.url);
}
var server = http.createServer(handleRequest);
server.listen(PORT, function(){
console.log("Server listening on: http://localhost:%s", PORT);
});
var client = restify.createJsonClientAsync({
url: 'http://127.0.0.1:7070'
});
client.get("/foo").spread(function(req, res, obj) {
console.log(obj);
});
I only put together this simple example to prove it to myself after my production code didn't work. I can hit localhost:7070 with curl and I get the expected results.
In a nutshell: I need to execute 3 GET calls to a server before I can create a POST and hence my need for promises.
Anyone can shed some insight? I can't imagine this being simpler.
UPDATE
Apparently i did not read the question correctly, here is a working example of 2 gets using a promisified restify json client. you would just do another spread in the body of the second spread for your post.
var promise = require('bluebird');
var restify = require('restify');
promise.promisifyAll(restify.JsonClient.prototype);
var client = restify.createJsonClient({
url: 'http://localhost:8080',
version: '*'
});
client.getAsync('/api/resource/1').spread(function(req, res, obj) {
console.log('result 1', obj);
return client.getAsync('/api/resource/2').spread(function(req, res, obj) {
console.log('result 2', obj);
});
});
As I stated in my comments, I would not promisify restify itself. Instead I would use either a handler whose body executes promise code or a chain of handlers (which can also have promises in the body). restify should only receive the request and execute the handler.
I will use modified versions of the basic example from the restify page to illustrate each.
Promise in the message body using knex.js which returns a promise
var knex = require('knex')(connectionConfig);
var restify = require('restify');
function promisePost(req, res, next) {
// get 1
knex.select('*')
.from('table1')
.where('id', '=', req.body.table1_id)
.then(function(result1) {
// get 2
return knex.select('*')
.from('table2')
.where('id', '=', req.body.table2_id)
.then(function(result2) {
return knex('table3').insert({
table1_value: result1.value,
table2_value: result2.value
})
.then(function(result3) {
res.send(result3);
return next();
});
});
});
}
var server = restify.createServer();
server.use(restify.bodyParser());
server.post('/myroute', promisePost);
server.listen(8080, function() {
console.log('%s listening at %s', server.name, server.url);
});
now with chained handlers
var knex = require('knex')(connectionConfig);
var restify = require('restify');
function get1(req, res, next) {
knex.select('*').from('table1')
.where('id', '=', req.body.table1_id)
.then(function(result1) {
res.locals.result1 = result1;
return next();
});
}
function get2(req, res, next) {
knex.select('*').from('table2')
.where('id', '=', req.body.table2_id)
.then(function(result2) {
res.locals.result2 = result2;
return next();
});
}
function post(req, res, next) {
knex('table3').insert({
table1_value: res.locals.result1,
table2_value: res.locals.result2
})
.then(function(result3) {
res.send(result3);
return next();
});
}
var server = restify.createServer();
server.use(restify.bodyParser());
server.post('/myroute', get1, get2, post);
server.listen(8080, function() {
console.log('%s listening at %s', server.name, server.url);
});
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.
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.
I need to make a single middleware that will handle each response to web user. I try to make something like the following:
function ajaxResponseMiddleware(req, res, next) {
var code = res.locals._code || 200;
var data = res.locals._response;
res.json(code, data);
}
app.get('/ajax1', function(req, res, next){
// Do something and add data to be responsed
res.locals._response = {test: "data2"};
// Go to the next middleware
next();
}, ajaxResponseMiddleware);
app.get('/ajax2', function(req, res, next){
// Do something and add data to be responsed
res.locals._response = {test: "data2"};
res.locals._code = 200;
// Go to the next middleware
next();
}, ajaxResponseMiddleware);
The response is handled in ajaxResponseMiddleware function where I can add some default state for all my ajax responses.
One thing that I don't like in the approach above is the adding ajaxResponseMiddleware function in each route.
So what do you think about this approach? May you advise improvements or share your experience.
middleware is just a function function (req, res, next) {}
var express = require('express');
var app = express();
// this is the middleware, you can separate to new js file if you want
function jsonMiddleware(req, res, next) {
res.json_v2 = function (code, data) {
if(!data) {
data = code;
code = 200;
}
// place your modification code here
//
//
res.json(code, data)
}
next();
}
app.use(jsonMiddleware); // Note: this should above app.use(app.router)
app.use(app.router);
app.get('/ajax1', function (req, res) {
res.json_v2({
name: 'ajax1'
})
});
app.listen(3000);