我是初学者,当谈到nodeJS,AJAX请求和路由时。我在这里遵循教程nodejs, express example,并且一切都在服务器端工作。但是我不能为了我的生活而弄清楚如何将上传的文件(本例中是图像)显示回客户端。当我对位于seperate/uploads /目录中的文件提出请求时,我从服务器收到404响应。我假定这是一个路由的问题,但感到困惑如何创建明确的GET请求上传的文件NodeJS,Express,如何更新客户端来显示上传的文件
app.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var path = require('path');
var formidable = require('formidable');
var fs = require('fs');
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
//passport for login credentials
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy; //here we implement the strategy that passport uses
var crypto = require('crypto');
var sqlite3 = require('sqlite3');
var db = new sqlite3.Database('users.sqlite3');
var check;
db.serialize(function() {
db.run("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT, password TEXT, salt TEXT)");
console.log('user table created');
db.run("DELETE FROM users"); //clear table on run for debug
var stmt = db.prepare("INSERT INTO users VALUES (?,?,?,?)");
stmt.run('15', 'tg', 'tg', "333");
stmt.finalize();
db.each("SELECT username, password, id, salt FROM users", function(err, row) {
console.log(row.username + ": " + row.password + ": " + row.id + ': ' + row.salt);
});
});
//db.close();
function hashPassword(password, salt) {
console.log('password hashing');
var hash = crypto.createHash('sha256');
hash.update(password);
hash.update(salt);
return hash.digest('hex');
}
passport.use(new LocalStrategy(function(username, password, done) {
console.log('using local strat for passport');
db.get('SELECT salt FROM users WHERE username = ?', username, function(err, row) {
if (!row) return done(null, false);
var hash = hashPassword(password, row.salt);
console.log('done hashing');
db.get('SELECT username, id FROM users WHERE username = ? AND password = ?', username, hash, function(err, row) {
if (!row){
console.log('failure');
return done(null, false);
}
console.log('success');
return done(null, row);
});
});
}));
passport.serializeUser(function(user, done) {
console.log('serializing');
return done(null, user.id);
});
passport.deserializeUser(function(id, done) {
console.log('deserializing')
db.get('SELECT id, username FROM users WHERE id = ?', id, function(err, row) {
if (!row) return done(null, false);
return done(null, row);
});
});
///end user authentication
//on access to site, serve the user the login page
app.get('/', function(req, res){
res.sendFile(path.join(__dirname, 'views/home.html'));
});
//providing routing access for success/failure on login attempt
app.post('/login',
passport.authenticate('local', { successRedirect: '/home',
failureRedirect: '/fail' }));
app.get('/fail', function(req,res){
res.sendFile(path.join(__dirname, 'views/error.html'));
});
app.get('/home', function(req,res){
res.sendFile(path.join(__dirname, 'views/home.html'));
});
app.get('/login', function(req,res){
res.sendFile(path.join(__dirname, 'views/login.html'));
console.log('login unsuccessful');
});
app.get('/home', function(request, response) {
response.render('views/home');
});
app.get('/upload' , function(req, res){
res.sendFile(__dirname + '/uploads');
});
app.post('/upload', function(req, res){
// create an incoming form object
var form = new formidable.IncomingForm();
// specify that we want to allow the user to upload multiple files in a single request
form.multiples = true;
// store all uploads in the /uploads directory
form.uploadDir = path.join(__dirname, '/uploads');
// every time a file has been uploaded successfully,
// rename it to it's orignal name
form.on('file', function(field, file) {
fs.rename(file.path, path.join(form.uploadDir, file.name));
});
// log any errors that occur
form.on('error', function(err) {
console.log('An error has occured: \n' + err);
});
// once all the files have been uploaded, send a response to the client
form.on('end', function() {
res.end('success');
});
// parse the incoming request containing the form data
form.parse(req);
});
var server = app.listen(3000, function(){
console.log('Server listening on port 3000');
});
upload.js
'use strict'
$('.upload-btn').on('click', function(){
$('#upload-input').click();
$('.progress-bar').text('0%');
$('.progress-bar').width('0%');
});
$('#upload-input').on('change', function(){
var files = $(this).get(0).files;
if (files.length > 0){
// create a FormData object which will be sent as the data payload in the
// AJAX request
var formData = new FormData();
// loop through all the selected files and add them to the formData object
for (var i = 0; i < files.length; i++) {
var file = files[i];
// add the files to formData object for the data payload
formData.append('uploads[]', file, file.name);
}
$.ajax({
url: '/upload',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(data){
console.log('upload success');
},
xhr: function() {
// create an XMLHttpRequest
var xhr = new XMLHttpRequest();
// listen to the 'progress' event
xhr.upload.addEventListener('progress', function(evt) {
if (evt.lengthComputable) {
// calculate the percentage of upload completed
var percentComplete = evt.loaded/evt.total;
percentComplete = parseInt(percentComplete * 100);
// update the Bootstrap progress bar with the new percentage
$('.progress-bar').text(percentComplete + '%');
$('.progress-bar').width(percentComplete + '%');
// once the upload reaches 100%, set the progress bar text to done
if (percentComplete === 100) {
$('.progress-bar').html('Done');
console.log(formData);
showUploadedItem(file.name);
}
}
}, false);
return xhr;
}
});
}
});
function showUploadedItem (source) {
var list = document.getElementById("image-list"),
li = document.createElement("li"),
img = document.createElement("img");
img.src = source;
li.appendChild(img);
list.appendChild(li);
}
'File'对象默认没有'.path'属性。 – guest271314