I am using latest version of express no.3 . I have read the docs and did exactly as was written but it is still not working as it suppose to .I get file in my upload dir after submit but then everything stops and callback function from app.post doesn't fire . The code:
HTML-JADE
form(action="/upload", method="post", enctype="multipart/form-data")
input(type="file", name="image")
input(type='submit', value='submit')
App.js
var express = require('express')
, user = require('./routes/user')
, http = require('http')
, path = require('path')
, mongo = require('mongodb')
, Server = mongo.Server
, Db = mongo.Db
, routes = require('./routes')
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser({uploadDir:'./upload'}));
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));
app.use(express.session());
app.use(app.router);
app.use(require('stylus').middleware(__dirname + '/public'));
app.use(express.static(path.join(__dirname, 'public')));
});
app.post('/upload', function(req, res) {
console.log(req.files.image) // this doesn't fire at all - no matter what i write here
res.send(200) //doesn't run also
});
You need to return a response after reading the data. Without returning a response, express has no idea of when your response is finished and node will not close the connection to the client.
try this:
app.post('/upload', function(req, res) {
console.log(req.files.image);
req.on('data', function(raw) {
console.log('received data');
});
req.on('end', function() {
console.log('end');
res.send(200);
});
}
Try sending a simple response to the user.
app.post('/upload', function(req, res) {
console.log(req.files.image);
res.write('File Uploaded !!');
res.end();
}
Update
You should try changing the format to
app.post('/upload', function(err,req,res,next){
//Check for errors then handle it
}
Can't tell much until I know what errors you are getting, since file is being uploaded to upload dir bodyParser is working fine. Maybe your route is being handled by another function, or not handled at all. app.router is code that calls the callback .
When you do app.get('/upload', function(req, res) { ... }); it is the router that actually invokes the callback function to process the request. Can you confirm if you can do app.get('/upload',...); the html-jade file succesfully. If not then there is a problem in your routes.
Finally I found solution - that was because i used node 0.9.6 -pre. After change to 0.8.21 everything works fine.
Thanks all for your help.
Related
I really apologize if I'm leaving something out and am totally stupid, but I've checked and checked over again a number of times, and the file upload functionality is just not working over here. I made a super minimal app to demonstate. Just generated a new express app with the most up-to-date version (3.4.7) and added the least i could to make a file upload work.
Here's my app.js file
/**
* Module dependencies.
*/
var express = require('express');
var http = require('http');
var path = require('path');
var app = express();
// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/tasks', function(req, res) {
res.render('form');
});
app.post('/tasks', function(req, res) {
console.log(req.files);
res.send('ok');
});
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
exports = module.exports = app;
And here's my form.jade view file:
doctype html
html
head
title Task Upload
body
form(action='/tasks', method='post', enctype='multipart/form-data')
input(name='task', type='file')
input(type='submit')
Everytime I try to upload a file, req.files logs out undefined. Can anyone save me out from this problem?
Add the following in your app.js
app.configure(function(){
app.use(express.methodOverride());
app.use(express.bodyParser({keepExtensions:true,uploadDir:path.join(__dirname,'/files'}));
});
And then try to access as follows;
req.files.task
It is recommended not to use bodyParser, but to simply define the type of handling you want. In your case since its file uploading, you can enable it as follows
app.configure(function(){
app.use(express.methodOverride());
app.use(express.multipart());
});
You can read about why using bodyParser() is not a good idea in the following link.
http://andrewkelley.me/post/do-not-use-bodyparser-with-express-js.html
In Express 4, req.files is no longer available on the req object by default.
To access uploaded files on the req.files object, use multipart-handling middleware like busboy, multer, formidable, multiparty, connect-multiparty,.
I have written a code snippet using backbone which POST's data to the urlRoute .
(function(){
"use strict"
window.Course = Backbone.Model.extend({
defaults:{
title:''
},
urlRoot:"courses/"
});
var courses = new Course({title:"Sending a Post request to the node-express backend,but how to access this in the backend"});
courses.save();
})();
I have used node.js - express framework in the backend ,i want to know how to retrieve the value of the title attribute using the app.post('/courses',function(req,res){}) method .
This is the node.js backend ,The control comes to the app.post method , but just want ot how to the access the model value in the posted data .
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path');
var app = express();
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use(express.errorHandler());
});
app.post('/courses',function(req,res) {
console.log('Request successfully recieved');
console.log("how do i get the posted data here !!");
});
app.get('/', routes.index);
app.get('/users', user.list);
http.createServer(app).listen(app.get('port'), function(){
console.log("Express server listening on port " + app.get('port'));
});
You can find your request data in req.body (more on that http://expressjs.com/api.html#req.body).
In your case you can do like this:
app.post('/courses',function(req,res) {
console.log(req.body.title);
});
I am trying to make az ExtJS application with a Node.js server. My server code currently looks like this:
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.sendfile(filedir + '/index.html');
});
app.get('/employees', function(req, res){
console.log("hello");
});
app.listen(3000);
When I open localhost:3000 in a browser, the html file is load, but not correctly. Checking in firebug I see that itt cannot find the linked files in html. For example
"NetworkError: 404 Not Found - http://localhost:3000/ext-4/ext-debug.js".
This is quite logical, since the file doesn't exist on that URL. My question would be how to fix this issue, so it could find every single linked file on my filesystem.
I'm clearly doing something wrong or missing something, I am totally new in node.
Doesn't look like you're configuring Express' static file handler.
Try adding this code:
app.configure(function() {
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.bodyParser());
app.use(express.logger("short"));
});
It would go right after var app = ... like this:
var express = require('express');
var app = express();
app.configure(function() {
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.bodyParser());
app.use(express.logger("short"));
});
app.get('/', function (req, res) {
res.sendfile(filedir + '/index.html');
});
app.get('/employees', function(req, res){
console.log("hello");
});
app.listen(3000);
And then place your static files under the ./public directory.
You'll want to use some static middleware such as: http://www.senchalabs.org/connect/static.html
note express inherits connect so you can
app.use(express.static(filedir));
Or the full thing:
var express = require('express');
var app = express();
app.use(express.static(filedir));
app.get('/employees', function(req, res){
console.log("hello");
res.send("hello");
});
app.listen(3000);
I want to post some data to server. The problem is that, it seems the server cannot receive the data.
So my post data is like this:
name=hello&email=there&message=sometext
and my server code is like this:
var url = require('url'),
express = require('express'),
http=require('http'),
path = require('path'),
nodemailer = require('nodemailer');
var app = express();
var server = http.createServer(app);
app.engine('.html', require('ejs').__express);
app.set('views', __dirname + '/views');
app.set('view engine', 'html');
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', function(req, res){
res.render('home');
});
app.use(express.bodyParser());
app.post('/', function(req, response){
console.log(req.body);
// console.log(request.body.name);
});
server.listen(4000);
console.log('server running ' + 'now ' + Date.now());
when the console.log(reg.body) run, the terminal output is "undefined"
All query strings output are parsed by default by app.use(express.bodyParser());.. simple solution to your problem is try logging req.query , something like
console.log(req.query);
move app.use(express.bodyParser())); ahead of app.use(express.static(path.join(__dirname, 'public')));
I have done this before... I don't follow what I'm doing wrong this time, but I've been struggling for a couple of hours and now consider myself mentally blocked. The corresponding code:
app.use(express.bodyParser());
app.use(i18next.handle);
app.use(express.methodOverride());
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/views');
app.set('view engine', 'swig');
app.set('view cache', false);
var session_store = new RedisStore({ client : redis_client});
app.use(express.errorHandler({ dumpExceptions : true, showStack : true}));
app.use(express.cookieParser());
app.use(express.session({ store : session_store, secret : SESSION_SECRET, key : "sid" }));
app.use(app.router);
Then when handling requests, here's just an example:
app.get('/session_test', function (req, res, next) {
console.log(req.session); //undefined
});
Connection to redis is working just fine. No errors are shown. Then, when trying to access it from the request, the req.session is undefined. The browser is sending the correct sid.
I'm no expert on the exact flow that occurs during the request, but after debugging, it seems as if the router was being called before the session middleware.
Thanks in advance for any and all the likely help. I will provide any code I can, I'm unsure what might be of your help.
Here's more code.
server.js
//Dependency modules
var express = require('express'),
app = express.createServer(),
//Application dependency modules
settings = require('./settings'), //app settings
routes = require('./routes'), //http routes
rtroutes = require('./rtroutes'); //real time communication routes (io)
var io = require('socket.io').listen(app);
var appWithSettings = settings.setup(io, app);
routes.settings.setup(appWithSettings);
rtroutes.settings.setup(io, appWithSettings);
No routes are added until routes.settings.setup is called. settings (which is the global settings) is a pretty big file. That's where all configuration is done. Settings are not added until settings.setup method is called too. Here's a cut of the file:
//Dependency modules
var express = require('express'),
redis = require('redis'),
//Important configuration values
var SESSION_SECRET = 'some secret thing which doesnt belong to stackoverflow!',
insert_other_variables_here = "lalala";
//Computed general objects
var RedisStore = require('connect-redis')(express),
redis_client = redis.createClient(REDIS_PORT, REDIS_HOST);
exports.setup = function (io, app) {
app.configure(function () {
app.use(express.bodyParser());
app.use(i18next.handle);
app.use(express.methodOverride());
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/views');
app.set('view engine', 'swig');
app.set('view cache', false);
var session_store = new RedisStore({ client : redis_client});
app.use(express.errorHandler({ dumpExceptions : true, showStack : true}));
app.use(express.cookieParser());
console.log("ABOUT TO ADD SESSION STORE MIDDLEWARE");
app.use(express.session({ store : session_store, secret : SESSION_SECRET, key : "sid" }));
console.log("AND NOW ADDED THE SESSION STORE MIDDLEWARE");
app.use(app.router);
});
app.configure('development', function () {
//some things in here, but nothing that affects app. I have commented this
//for debugging and it changed nothing
});
app.configure('production', function () {
//mostly configuration for io and some caching layers, as well as servers info
app.use(express.errorHandler());
app.use(express.logger({ stream : logFile }));
});
app.listen(WEB_PORT);
return {
app : app,
//some other stuff that isn't relevant
}
}
I have 25 routes split in 4 different files (somehow I didn't have a need for session until now, since I was delaying some parts and everything needed was done with Mongoose). Here's an example of how it is being done (with fake names):
routes/index.js
export.settings = require("./settings");
routes/settings.js
exports.setup = function (app_settings) {
require("./route1")(app_settings);
require("./route2")(app_settings);
require("./route3")(app_settings);
};
Here's a stripped out "route1" file ("routes/route1.js"):
module.exports = function (app_settings) {
var app = app_settings.app;
console.log("ABOUT TO ADD ROUTES")
app.get("/signin", function (req, res, next) {
console.log(req.session); //this will be undefined
});
app.get("/register", function (req, res, next) {
});
app.get('/language', function (req, res, next) {
});
app.post('/settings', function (req, res, next) {
});
console.log("ADDED ROUTES NOW!")
}
Whenever you define a route, the router gets automatically inserted into whatever the middleware stack is at the time (subsequent attempts to insert it deliberately will be ignored). Are you sure you aren't defining any routes before you set the session handler?
Forgot to update this: Ebohlman set me in the right track.
It was i18next. When calling one of the init method it sets up routes and it was forcing app.router to be forced into the handle stack sooner. My bad, I didn't realize that part of the code was interacting with the app object and it did.
There was no way the question could have been answered better than how he did with the information I gave, so I am marking his answer as right.
I should try sleeping more v.v