如何使用 Node.js 服务器将图像数据从前端保存到 Mongoose 数据库



我有一个使用node的后端.js还有一个使用jquery,javascript,ajax和bootstrap的前端。我想从前端上传图像并将其保存到猫鼬数据库。在这里,文件已成功加载,图像将位于名为/public/img的位置。但是如何使用 API 调用将这些图像信息保存到数据库中。
下面是我的代码:

后端代码节点.js、猫鼬

/服务器.js

var express =   require("express");
var multer  =   require('multer');
var path = require('path');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var app = express();
app.appname="photogallery";
//config mongoose
app.db = mongoose.createConnection('localhost/'+app.appname);
app.db.on('error', console.error.bind(console, 'mongoose connection error: '));
app.db.once('open', function () {
//Storage is all good
});
//Routes and acl
var router = express.Router();
require('./routes')(app, router, passport);
var file_url = '';
var storage =   multer.diskStorage({
destination: function (req, file, callback) {
callback(null, 'public/img/');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
file_url = file.fieldname + '-' + Date.now() + '.' + file.originalname.split('.')[file.originalname.split('.').length -1]
callback(null, file_url);
}
});
var upload = multer({ storage : storage}).single('userPhoto');
app.use(express.static(path.join(__dirname, '/public/')));
app.post('/api/photo',function(req,res){
upload(req,res,function(err) {
if(err) {
return res.end("Error uploading file.");
}
// res.end("File is uploaded");
res.json({error_code:0,err_desc:null,file_url:'img/'+file_url});
/*Now I want to save this file_url to image_url using api /api/photoGallery, please help me to save these information to the db */ 
});
});
//config express
app.set('secret','thisshouldnotbeinplaintext');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(passport.initialize());
app.use(router);

app.listen(5050,function(){
console.log("Working on port 5050");
});

/api/requests.js

'use strict';
var passport = require('passport');
var app = require('../app');
exports.init = function(pp) {
passport = pp;
app = pp;
return exports;
};
exports.root = function(req, res) {
res.send("Running");
};
//Add Image Data
exports.addData = function(req, res) {
var addData = req.app.db.model('Data');
var data = {  image_title  : req.body.image_title,
image_url    : "http://localhost:5050/"+req.body.image_url
}
var query = addData(data);
query.save(function(err){
if(err){
console.log(err.toString());
}
console.log('Image Saved Successfully');
res.json({ success: true });
});
};

/schema/data.js

'use strict';
exports = module.exports = function(app, mongoose) {
var dataSchema = new mongoose.Schema({
image_title  :  { type: String, unique: true,  lowercase: true },
image_url    :  { type: String, unique: true,  lowercase: true }
});
app.db.model('Data', dataSchema);
};

/型号.js

'use strict';
module.exports = function(app, mongoose) {
//Mongoose Schemas
require('./schema/Data')(app, mongoose);
};

/路线.js

'use strict';
module.exports = function(app, router, passport) {
var requests = require('./api/requests').init(passport);
router.get('/', requests.root);
router.post('/api/addPhoto/v1', requests.addData);
router.get('/api/getPhoto/v1', requests.getPhoto);
};

例如 Json 将如下所示

{
image_title: exampleImage,
image_url: xyzscjnscncsl.exampleImage.png
}

前端代码Jquery,JavaScript,Ajax,HTML

/public/index.html

<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Please Upload Image</h4>
</div>
<form id="uploadForm" enctype="multipart/form-data" action="/api/photo" method="post">
<div class="modal-body">
<div class="form-group">
<input type="text" class="form-control" id="imagetitle" placeholder="Image Title">
</div>
<div class="form-group">
<input type="file" class="form-control" id="input-image" name="userPhoto" accept="image/*">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancle</button>
<button type="submit" class="btn btn-default" value="Upload Image" name="submit">Save</button>
</div>
<span id = "status"></span>
</form>
</div>
</div>
</div>

/public/javascript/image.js

如何使用 API 调用将图像数据从这里保存到猫鼬数据库?

$(document).ready(function() {
$('#uploadForm').submit(function() { 
$("#status").empty().text("File is uploading...");
$(this).ajaxSubmit({
error: function(xhr) {
status('Error: ' + xhr.status);
},
success: function(response) {
console.log(response)
$("#status").empty().text(response);
}
});
return false;
});    
});

我不建议大多数项目这样做(正如保罗评论的那样),但这并不复杂。

从客户端获取图像文件后,读取图像数据(fs.readFile)并使用缓冲区将其编码为 base64 并保存到数据库中,这样您将使用更少的空间来存储数据。然后,在需要二进制文件时解码 base64 数据。

fs.readFile('foo.png', function(err, data) {
const base64img = new Buffer(data).toString('base64');
});

有一些 npm 模块可以简化一些,例如base64-img

我建议你使用 busboy 而不是 multer,因为 multer 会保存到磁盘,busboy 会返回一个流,你可以通过管道传输到任何你想要的(甚至是 mongoDB)。

Gridfs-stream是一个很好的模块,可以使用gridfs功能将数据流式传输到mongoDB。

以下是它们的基本用法:

var Busboy = require('busboy');
var gfs = require('gridfs-stream')(mongoose.connection.db, mongoose.mongo)

//express middleware:
function (req, res) {
var busboy = new Busboy({ headers: req.headers, limits: { fileSize: 1024, files: 1 } });
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
var ws = gfs.createWriteStream({ filename: filename, content_type: mimetype});
ws.on('error', function(err) {
console.error(err);
res.send(500, err);
});
ws.on('finish', () => {/*do something when streaming ends*/});
file.pipe(ws);
}
busboy.on('error', function(err) {
console.error(err);
res.send(500, err);
});
req.pipe(busboy);
}

/*这是解决方案 */

/服务器.js

var express =   require("express");
var multer  =   require('multer');
var path = require('path');
var passport = require('passport');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');

var app = express();
app.appname="photogallery";
//config mongoose
app.db = mongoose.createConnection('localhost/'+app.appname);
app.db.on('error', console.error.bind(console, 'mongoose connection error: '));
app.db.once('open', function () {
});

//config data models
require('./models')(app, mongoose);
//Routes and acl
var router = express.Router();
require('./routes')(app, router, passport);
/* Image Logic */
var file_url = '';
var storage =   multer.diskStorage({
destination: function (req, file, callback) {
callback(null, 'public/img/');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
file_url = file.fieldname + '-' + Date.now() + '.' + file.originalname.split('.')[file.originalname.split('.').length -1];
callback(null, file_url);
}
});
var upload = multer({ storage : storage}).single('userPhoto');
app.use(express.static(path.join(__dirname, '/public/')));
app.post('/api/photo',function(req,res){
upload(req,res,function(err) {
if(err) {
return res.end("Error uploading file.");
}
//res.end("File is uploaded");
//console.log("file_url", file_url);
res.json({error_code:0,err_desc:null, file_url:'img/'+file_url});
});
});
//config express
app.set('secret','thisshouldnotbeinplaintext');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(passport.initialize());
app.use(router);
app.listen(5050,function(){
console.log("Working on port 5050");
});

/api/requests.js

'use strict';
var jwt = require('jsonwebtoken');
var passport = require('passport');
exports.init = function(pp) {
passport = pp;
return exports;
};
exports.root = function(req, res) {
res.send("Running");
};
/* Save Image Data Function */
exports.addData = function(req, res) {
var addData = req.app.db.model('Data');
var data = {
img_title   : req.body.img_title,
img_url     : "http://localhost:5050/"+req.body.img_url
}
var query = addData(data);
query.save(function (err, data) {
if (err) {
console.log(err.toString());
} else {
console.log('Image saved Successfully');
res.json(data);
}
});
};
/* Get Image Data Function */
exports.getPhoto = function(req, res) {
var getPhoto = req.app.db.model("Data");
var query = getPhoto.find(function(err, data){
if(err) {
console.log("Not Found");
} else  {
res.json({'data': data});
}
});
};

/schema/data.js

'use strict';
module.exports = function(app, mongoose) {
var dataSchema = new mongoose.Schema({
img_title        : { type: String, default: '' },
img_url          : { type: String, default: '' }
});
app.db.model('Data', dataSchema);
};

/型号.js

'use strict';
module.exports = function(app, mongoose) {
//Mongoose Schemas
require('./schema/Data')(app, mongoose);
}

/路线.js

'use strict';
module.exports = function(app, router, passport) {
var requests = require('./api/requests').init(passport);
router.get('/', requests.root);
router.post('/api/addPhoto/v1', requests.addData);
router.get('/api/getPhoto/v1', requests.getPhoto);
};

/public/index.html

<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">&times;</button>
<h4 class="modal-title">Please Upload Image</h4>
</div>
<form id="uploadForm" enctype="multipart/form-data" action="/api/photo" method="post">
<div class="modal-body">
<div class="form-group">
<input type="text" class="form-control" id="imagetitle" placeholder="Image Title">
</div>
<div class="form-group">
<input type="file" class="form-control" id="input-image" name="userPhoto" accept="image/*">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancle</button>
<button type="submit" class="btn btn-default" value="Upload Image" name="submit">Save</button>
</div>
<span id = "status"></span>
</form>
</div>
</div>
</div>

/public/javascript/image.js

/* 如何使用 api 调用将图像数据从前端保存到猫鼬 */

$(document).ready(function() {
$('#uploadForm').submit(function() {
$("#status").empty().text("File is uploading...");
var imageTitle = $("#imagetitle").val();
$(this).ajaxSubmit({
error: function(xhr) {
status('Error: ' + xhr.status);
},
success: function(response) {
var localFile = response.file_url;
$.ajax({
url: "/api/addPhoto/v1",
data: {
img_title: imageTitle,
img_url: localFile
},
method: 'post',
dataType: 'json',
success: function(data) {
var html = "";
html+= "<div class='col-md-3 col-md-offset-1'>";
html+= "<div class='img-box imgClass'>";
html+= "<img src='"+data.img_url+"'>";
html+= "</div> </div>";
$('.myimage').append(html);
$('#myModal').modal('hide');
},
error: function(xhr, status) {
alert("Sorry, there was a problem!");
}
});
}
});
return false;
});
});
$(function(){
$.get("/api/getPhoto/v1", function(response) {
//console.log(response.data.length);
var html = "";
for(var i = 0; i< response.data.length ; i++){
html+= "<div class='col-md-3 col-md-offset-1'>";
html+= "<div class='img-box imgClass'>";
html+= "<img src='"+response.data[i].img_url+"'>";
html+= "</div> </div>"
}
$('.myimage').html(html);
});
});

最新更新