将客户端的图片上传到JSON文件,并通过节点/快捷方式保存到mongo

我正在使用MEAN堆栈。 我使用meanjs.org yeoman生成器创build了一个CRUD模块。 我正在扩展function来保存具有几个子文档的文档。 我的方法基本上是构buildJSON客户端,将其添加到主文档,然后保存主文档。 这很好,除了当我试图build立一个存储图像数据的子文件。

我使用HTML5 FileReader的readAsDataURL来获取图像数据的base64编码版本,并将其存储在名为幻灯片的子文档中。 这似乎工作,因为我可以上传图像,并用ng-repeat在我的对象中看到它们。 当我尝试更新主文档时,它不起作用。 Firefoxdebugging控制台显示如下所示:

PUT XHR http:// localhost:3000 / galleries / 55e888e0cec8658491097f12

当我点击这个细节:

请求URL: http:// localhost:3000 / galleries / 55e888e0cec8658491097f12请求方法:PUT状态码:HTTP / 1.1 500内部服务器错误

我得到这样的错误后,没有保存,甚至没有图像添加一个新的子文档。

我的图片都在300K或更less,不是超大,但我想知道是否有一些问题与JSON持有这么多的数据? 或者,也许这是一个问题,mongoose? 我真的不知道如何去debugging后端,这一切都是自动生成的。

这是我的mongoose模式:

'use strict'; /** * Module dependencies. */ var mongoose = require('mongoose'), Schema = mongoose.Schema; //CommentSchema var CommentSchema = new Schema({ user: String, comment: String }); //SlideSchema var SlideSchema = new Schema({ image: Buffer, order: Number }); //AuthorSchema var AuthorSchema = new Schema({ fname: String, lname: String, title: String }); //PosterSchema var PosterSchema = new Schema({ title: String, authors: [AuthorSchema], slides: [SlideSchema], comments: [CommentSchema] }); //Gallery Schema var GallerySchema = new Schema({ conference_name: { type: String, default: '', required: 'Please enter Conference Name', trim: true }, access_code: { type: String, index: { unique: true }, required: 'Please enter a unique Access Code', trim: true }, created: { type: Date, default: Date.now }, user: { type: Schema.ObjectId, ref: 'User' }, posters: [PosterSchema] }); mongoose.model('Gallery', GallerySchema); mongoose.model('Poster', PosterSchema); mongoose.model('Author', AuthorSchema); mongoose.model('Slide', SlideSchema); 

CRUD模块是为图库生成的。 在'view-gallery-client.view.html'中,我添加了一个控件来加载模式窗口来添加海报。 添加海报生成必要的JSON对象,将其推送到画廊的“海报”子文档,然后更新画廊。 模式窗口还构build“作者”和“幻灯片”子文档。

这里是“添加海报”模式的控制器和视图:

 controller('AddPosterModalController', ['$scope','Upload','$modalInstance','$timeout', function ($scope, Upload, $modalInstance, $timeout) { $scope.poster = {}; $scope.poster.authors = []; $scope.poster.slides = []; $scope.images = []; $scope.dynamic = 50; $scope.showAuthors = true; $scope.add_author = function () { $scope.poster.title = $scope.title; var author = { fname: $scope.fname, lname: $scope.lname, title: $scope.atitle }; $scope.poster.authors.push(author); $scope.fname = ''; $scope.lname = ''; $scope.atitle = ''; }; $scope.remove_author = function(author) { for(var i=0; i<$scope.poster.authors.length; i++) { if(author === $scope.poster.authors[i]) $scope.poster.authors.splice(i,1); } }; $scope.add = function() { alert('closing modal and returning poster: ' + JSON.stringify($scope.poster)); $modalInstance.close($scope.poster); }; $scope.remove_slide = function(slide) { for(var i=0; i<$scope.poster.slides.length; i++) { if($scope.poster.slides[i] === slide) $scope.poster.slides.splice(i,1); } }; $scope.change_slide_order = function(oldorder, amount) { var neworder = parseInt(oldorder + amount); oldorder = parseInt(oldorder); //we won't swap indices, but if(neworder >= 0 && neworder < $scope.poster.slides.length) { var slide1 = -1; var slide2 = -2; for(var i=0; i<$scope.poster.slides.length; i++) { if($scope.poster.slides[i].order === oldorder) slide1 = i; else if($scope.poster.slides[i].order === neworder) slide2 = i; } //swap the slides, not the index, but the order value $scope.poster.slides[slide1].order = neworder; $scope.poster.slides[slide2].order = oldorder; } }; //handle slide uploads $scope.add_slides = function(event) { var files = $scope.files = event.target.files; for(var i=0; i<files.length; i++) { var reader = new FileReader(); var file = files[i]; reader.onload = $scope.imageLoaded; reader.readAsDataURL(file); } }; $scope.imageLoaded = function(e) { //timeout should solve the $digest error //safer than $apply $timeout(function(){ var data = e.target.result; //data = window.btoa(data); var order = $scope.poster.slides.length; //build a JSON slide object var slide = { image: data, order: order }; //add the image to the poster $scope.poster.slides.push(slide); }); }; } ]); 

并查看:

 <div class="modal-header"> <h3>Add a Poster to the Gallery</h3> </div> <div class="modal-body"> <form class="form-horizontal" data-ng-submit="add_poster()" novalidate> <fieldset> <div class="row"> <div class="form-group col-md-12"> <label class="control-label" for="title">Poster Title</label> <div class="controls"> <input type="text" data-ng-model="title" id="title" class="form-control" placeholder="Poster Title" required> </div> </div> </div> <div class="row"><h3 ng-click="showAuthors = !showAuthors">Authors ({{poster.authors.length}})</h3></div> <div class="row" ng-repeat="author in poster.authors" collapse="!showAuthors"> <a class="btn btn-primary" data-ng-click="remove_author(author)"> <i class="glyphicon glyphicon-minus"></i> </a> <span>{{author.title}} {{author.fname}} {{author.lname}}</span> </div> <div class="row"> <div class="form-group col-md-4"> <label class="control-label" for="fname">First Name</label> <div class="controls"> <input type="text" data-ng-model="fname" id="fname" class="form-control" placeholder="First Name" required> </div> </div> <div class="form-group col-md-4"> <label class="control-label" for="lname">Last Name</label> <div class="controls"> <input type="text" data-ng-model="lname" id="lname" class="form-control" placeholder="Last Name" required> </div> </div> <div class="form-group col-md-3"> <label class="control-label" for="atitle">Title</label> <div class="controls"> <input type="text" data-ng-model="atitle" id="atitle" class="form-control" placeholder="Title" required> </div> </div> <div class="form-group col-md-1"> <label class="control-label">Add</label> <div class="controls"> <a class="btn btn-primary" data-ng-click="add_author()"> <i class="glyphicon glyphicon-plus"></i> </a> </div> </div> </div> <div class="row"> <h3> Slides ({{poster.slides.length}}) <label for="files" class="btn btn-primary glyphicon glyphicon-plus"></label> <input type="file" id="files" ng-model="mFiles" multiple collapse="true" accept="image/*" onchange="angular.element(this).scope().add_slides(event)"/> </h3> <div class="col-md-3" ng-repeat="slide in poster.slides | orderBy:'order'"> <img width="160" height="95" src="{{slide.image}}"/> ({{slide.order}}) <a class="btn btn-primary" data-ng-click="remove_slide(slide);"> <i class="glyphicon glyphicon-minus"></i> </a> <a class="btn btn-primary" data-ng-click="change_slide_order(slide.order,-1);"> <i class="glyphicon glyphicon-arrow-left"></i> </a> <a class="btn btn-primary" data-ng-click="change_slide_order(slide.order,1);"> <i class="glyphicon glyphicon-arrow-right"></i> </a> </div> </div> </fieldset> </form> </div> <div class="modal-footer"> <button class="btn-primary" ng-click="add()" class="btn btn-default">Add Poster</button> </div> 

任何build议都值得赞赏。 我试图保留所有的数据库,因为图像很小,而且这只供less数人使用,而不需要太多的缩放。 我现在甚至不想考虑跟踪文件系统上的东西。

编辑 – 解决

我已经解决了这个问题。 愚蠢的是,我没有足够的重视节点/快递控制台日志。 我得到一个错误:

错误:请求实体太大

事实certificate,bodyParser有默认的限制,它处理通过http传入的数据。 由于REST服务支持CRUD模块,所以我达到了极限。

解决的办法是在app / config / express.js中configurationbodyParser:

app.use(bodyParser.urlencoded({extended:true})); app.use(bodyParser.json());

变为:

app.use(bodyParser.urlencoded({extended:true,limit:'20mb'})); app.use(bodyParser.json({limit:'20mb'}));

确保限制设置为小写,即“20mb”不是“20MB”,这是行不通的。