分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 前端开发

Node 实现一个MVC相册资源管理器

发布时间:2023-09-06 01:25责任编辑:苏小强关键词:MVCNode

暂没有数据库,所以做的也是本地的资源管理器。

总体设计:

 app.js:

var express = require("express");var app = express();//控制器var router = require("./controller");//设置模版引擎app.set("view engine","ejs");//路由中间件//静态页面app.use(express.static("./public"));app.use(express.static("./uploads"));//get/的时候,上层函数回调的时候传入req,res//首页app.get("/",router.showIndex);app.get("/:albumName",router.showAlbum);app.get("/up",router.showUp);app.post("/up",router.doPost);//404app.use(function (req,res) { ???res.render("err");});app.listen(3000);

用express静态出public和uploads文件夹,用来放资源文件,然后分别路由主页,相册文件夹,上传页面,上传表单处理。

然后在控制层的controller来控制前台和后台的交互

router.js:

var file = require("../models/file.js");var formidable = require("formidable");var path = require("path");var fs = require("fs");var sd = require("silly-datetime");exports.showIndex = function (req,res,next) { ???//错误的,传统的思维,不是Node的思维。 ???// res.render("index",{ ???// ????//注意这里异步的,遇到阻塞,会直接呈递模版引擎,所以这种写法是错误的,小函数会没执行完,就呈递了 ???// ????"albums" : file.getAllAlbums() ???// }); ???//这就是Node.js的编程思维,就是所有的东西,都是异步的 ???//所以,内层函数,不是return回来东西,而是调用高层函数提供的 ???//回调函数。把数据当做回调函数的参数来使用。 ???file.getAllAlbums(function (err,allAlbums) { //这个function就是callback ???????//err是字符串 ???????if(err) { ???????????next(); ???????????return; ???????} ???????res.render("index",{ ???????????"albums" : allAlbums ???????}); ???})};//相册页exports.showAlbum = function (req,res,next) { ???//遍历相册中的所有图片 ???var albumName = req.params.albumName; ???//具体业务交给model ???file.getAllImagesByAlbumName(albumName,function (err,imagesArray) { ???????if(err) { ???????????next(); ???????????return; ???????} ???????res.render("album",{ ???????????"albumname" : albumName, ???????????"images" : imagesArray ???????}); ???}); ???};exports.showUp = function (req,res) { ???//命令file模块(我们自己写的函数)调用getAllAlbums函数 ???//得到所有文件夹名字之后做的事情,写在回调函数里面 ???file.getAllAlbums(function (err,albums) { ???????res.render("up",{ ???????????albums : albums ???????}); ???})}//上传表单exports.doPost = function (req,res) { ???var form = new formidable.IncomingForm(); ???????// "../"返回上一级 ???form.uploadDir = path.normalize(__dirname + "/../tempup/"); ???form.parse(req, function (err, fields, files,next) { ???????console.log(fields); ???????console.log(files); ???????//改名 ???????if(err) { ???????????next(); //这个中间件不受理这个请求了,往下走 ???????????return; ???????}; ???????//判断文件尺寸 ???????var size = parseInt(files.tupian.size); ???????if(size > 2000000) { ????????????res.send("图片尺寸应该小于2M"); ???????????//则删除这个文件 ???????????fs.unlink("files.tupian.path",function () { ???????????}); ???????????return; ???????} ???????var wenjianjia = fields.wenjianjia; ???????var oldpath = files.tupian.path ; ???????//还是加时间戳 ???????var ttt = sd.format(new Date(), "YYYMMDDHHmmss"); ???????var ran = parseInt(Math.random() * 89999 + 10000); ???????var extname = path.extname(files.tupian.name); ???????var newpath = path.normalize(__dirname + "/../uploads/" + wenjianjia + "/" + ttt + ran + extname); ???????fs.rename(oldpath,newpath,function (err) { ???????????if(err) { ???????????????res.send("改名失败"); ???????????????return; ???????????} ???????????res.send("成功"); ???????}); ???});}

底层的真正处理的模型层的file.js,注意的是由于这里没用es6的先进写法,所以很多是异步语句,正常的return返回是不行的,需要递归迭代来获得所有数据,用callback回调处理

var fs = require("fs");//这个函数的callback中含有两个参数,一个是err//另一个是存放所有文件夹名字的array。exports.getAllAlbums = function (callback) { ???fs.readdir("./uploads", function (err,files) { ???????if(err) { ???????????callback("没有找到upload文件",null); ???????} ???????var allAlbums = []; ???????(function iterator(i) { ???????????if (i == files.length) { ???????????????//遍历结束 ???????????????console.log(allAlbums); ???????????????//执行完了之后,执行回调函数 ???????????????callback(null,allAlbums); ???????????????return; ???????????} ???????????fs.stat("./uploads/" + files[i], function (err, stats) { ???????????????if(err) { ???????????????????callback("找不到文件" + files[i],null); ???????????????} ???????????????if (stats.isDirectory()) { ???????????????????allAlbums.push(files[i]); ???????????????} ???????????????iterator(i + 1); ???????????}); ???????})(0); ???});}//通过文件名,得到所有图片exports.getAllImagesByAlbumName = function (albumName,callback) { ???fs.readdir("./uploads/" + albumName, function (err,files) { ???????if(err) { ???????????callback("没有找到upload文件",null); ???????????return; ???????} ???????var allImages = []; ???????(function iterator(i) { ???????????if (i == files.length) { ???????????????//遍历结束 ???????????????console.log(allImages); ???????????????//执行完了之后,执行回调函数 ???????????????callback(null,allImages); ???????????????return; ???????????} ???????????fs.stat("./uploads/" + albumName + "/" + files[i], function (err, stats) { ???????????????if(err) { ???????????????????callback("找不到文件" + files[i],null); ???????????????????return; ???????????????} ???????????????if (stats.isFile()) { ???????????????????allImages.push(files[i]); ???????????????} ???????????????iterator(i + 1); ???????????}); ???????})(0); ???});}

 剩下的就是view视图层的前端样式了,用的ejs模板和bootstrap样式:

主页index.js:

<!DOCTYPE html><html lang="zh-CN"><head> ???<meta charset="utf-8"> ???<meta http-equiv="X-UA-Compatible" content="IE=edge"> ???<meta name="viewport" content="width=device-width, initial-scale=1"> ???<title>littleAlbum</title> ???<link href="css/bootstrap.min.css" rel="stylesheet"> ???<script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script> ???<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> ???<style type="text/css"> ???????.row h4 { ???????????text-align: center; ???????} ???</style></head><body><nav class="navbar navbar-default"> ???<div class="container-fluid"> ???????<!-- Brand and toggle get grouped for better mobile display --> ???????<div class="navbar-header"> ???????????<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> ???????????????<span class="sr-only">Toggle navigation</span> ???????????????<span class="icon-bar"></span> ???????????????<span class="icon-bar"></span> ???????????????<span class="icon-bar"></span> ???????????</button> ???????????<a class="navbar-brand" href="#">小小相册</a> ???????</div> ???????<!-- Collect the nav links, forms, and other content for toggling --> ???????<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> ???????????<ul class="nav navbar-nav"> ???????????????<li class="active"><a href="/">全部相册 <span class="sr-only">(current)</span></a></li> ???????????????<li><a href="up">上传</a></li> ???????????????<li class="dropdown"> ???????????????????<ul class="dropdown-menu"> ???????????????????????<li><a href="#">Action</a></li> ???????????????????????<li><a href="#">Another action</a></li> ???????????????????????<li><a href="#">Something else here</a></li> ???????????????????????<li role="separator" class="divider"></li> ???????????????????????<li><a href="#">Separated link</a></li> ???????????????????????<li role="separator" class="divider"></li> ???????????????????????<li><a href="#">One more separated link</a></li> ???????????????????</ul> ???????????????</li> ???????????</ul> ???????</div><!-- /.navbar-collapse --> ???</div><!-- /.container-fluid --></nav><div class="container"> ???<div class="row"> ???????<% for(var i = 0; i < albums.length; i++){ %> ???????<div class="col-xs-6 col-md-3"> ???????????<a href="<%= albums[i] %>" class="thumbnail"> ???????????????<img src="images/wenjianjia2.jpg" alt="..."> ???????????</a> ???????????<h4><%= albums[i] %></h4> ???????</div> ???????<% } %> ???</div></div><!--运行之后views和public是在一起的--><script src="js/jquery-1.11.3.min.js"></script><script src="js/bootstrap.min.js"></script></body></html>

相册页album.ejs:

<!DOCTYPE html><html lang="zh-CN"><head> ???<meta charset="utf-8"> ???<meta http-equiv="X-UA-Compatible" content="IE=edge"> ???<meta name="viewport" content="width=device-width, initial-scale=1"> ???<title>littleAlbum</title> ???<link href="/css/bootstrap.min.css" rel="stylesheet"> ???<script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script> ???<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> ???<style type="text/css"> ???????.row h4 { ???????????text-align: center; ???????} ???</style></head><body><nav class="navbar navbar-default"> ???<div class="container-fluid"> ???????<!-- Brand and toggle get grouped for better mobile display --> ???????<div class="navbar-header"> ???????????<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> ???????????????<span class="sr-only">Toggle navigation</span> ???????????????<span class="icon-bar"></span> ???????????????<span class="icon-bar"></span> ???????????????<span class="icon-bar"></span> ???????????</button> ???????????<a class="navbar-brand" href="#">小小相册</a> ???????</div> ???????<!-- Collect the nav links, forms, and other content for toggling --> ???????<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> ???????????<ul class="nav navbar-nav"> ???????????????<li class="active"><a href="/">全部相册 <span class="sr-only">(current)</span></a></li> ???????????????<li><a href="/up">上传</a></li> ???????????????<li class="dropdown"> ???????????????????<ul class="dropdown-menu"> ???????????????????????<li><a href="#">Action</a></li> ???????????????????????<li><a href="#">Another action</a></li> ???????????????????????<li><a href="#">Something else here</a></li> ???????????????????????<li role="separator" class="divider"></li> ???????????????????????<li><a href="#">Separated link</a></li> ???????????????????????<li role="separator" class="divider"></li> ???????????????????????<li><a href="#">One more separated link</a></li> ???????????????????</ul> ???????????????</li> ???????????</ul> ???????</div><!-- /.navbar-collapse --> ???</div><!-- /.container-fluid --></nav><div class="container"> ???<ol class="breadcrumb"> ???????<li><a href="/">全部相册</a></li> ???????<li class="active"><%= albumname %></li> ???</ol> ???<div class="row"> ???????<% for(var i = 0; i < images.length; i++){ %> ???????<div class="col-xs-6 col-md-3"> ???????????<a href="#" class="thumbnail"> ???????????????<img src="<%= images[i] %>" > ???????????</a> ???????????<h4></h4> ???????</div> ???</div> ???<% } %></div><!--运行之后views和public是在一起的--><script src="/js/jquery-1.11.3.min.js"></script><script src="/js/bootstrap.min.js"></script></body></html>

up.ejs:

<!DOCTYPE html><html lang="zh-CN"><head> ???<meta charset="utf-8"> ???<meta http-equiv="X-UA-Compatible" content="IE=edge"> ???<meta name="viewport" content="width=device-width, initial-scale=1"> ???<title>小小相册</title> ???<link href="/css/bootstrap.min.css" rel="stylesheet"> ???<script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script> ???<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> ???<style type="text/css"> ???????.row h4 { ???????????text-align: center; ???????} ???</style></head><body><nav class="navbar navbar-default"> ???<div class="container-fluid"> ???????<!-- Brand and toggle get grouped for better mobile display --> ???????<div class="navbar-header"> ???????????<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> ???????????????<span class="sr-only">Toggle navigation</span> ???????????????<span class="icon-bar"></span> ???????????????<span class="icon-bar"></span> ???????????????<span class="icon-bar"></span> ???????????</button> ???????????<a class="navbar-brand" href="#">小小相册</a> ???????</div> ???????<!-- Collect the nav links, forms, and other content for toggling --> ???????<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> ???????????<ul class="nav navbar-nav"> ???????????????<li class="active"><a href="/">全部相册 <span class="sr-only">(current)</span></a></li> ???????????????<li><a href="up">上传</a></li> ???????????????<li class="dropdown"> ???????????????????<ul class="dropdown-menu"> ???????????????????????<li><a href="#">Action</a></li> ???????????????????????<li><a href="#">Another action</a></li> ???????????????????????<li><a href="#">Something else here</a></li> ???????????????????????<li role="separator" class="divider"></li> ???????????????????????<li><a href="#">Separated link</a></li> ???????????????????????<li role="separator" class="divider"></li> ???????????????????????<li><a href="#">One more separated link</a></li> ???????????????????</ul> ???????????????</li> ???????????</ul> ???????</div><!-- /.navbar-collapse --> ???</div><!-- /.container-fluid --></nav><div class="container"> ???<div class="row"> ???????<form style = "width: 40%" method="post" enctype="multipart/form-data" action = "#"> ???????????<div class="form-group"> ???????????????<label for="exampleInputFile">选择文件夹</label> ???????????????<select class="form-control" name = "wenjianjia"> ???????????????????<% for(var i = 0; i < albums.length; i++) {%> ???????????????????<option><%= albums[i] %></option> ???????????????????<%}%> ???????????????</select> ???????????</div> ???????????<div class="form-group"> ???????????????<label for="exampleInputFile">选择图片</label> ???????????????<p>尺寸小于2M</p> ???????????????<input type="file" id="exampleInputFile" name = "tupian"> ???????????????<p class="help-block">Example block-level help text here.</p> ???????????</div> ???????????<button type="submit" class="btn btn-default">上传</button> ???????</form> ???</div></div><!--运行之后views和public是在一起的--><script src="/js/jquery-1.11.3.min.js"></script><script src="/js/bootstrap.min.js"></script></body></html>

err.ejs:

<!DOCTYPE html><html lang="zh-CN"><head> ???<meta charset="utf-8"> ???<meta http-equiv="X-UA-Compatible" content="IE=edge"> ???<meta name="viewport" content="width=device-width, initial-scale=1"> ???<title>littleAlbum</title> ???<link href="/css/bootstrap.min.css" rel="stylesheet"> ???<script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script> ???<script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> ???<style type="text/css"> ???????.row h4 { ???????????text-align: center; ???????} ???</style></head><body><nav class="navbar navbar-default"> ???<div class="container-fluid"> ???????<!-- Brand and toggle get grouped for better mobile display --> ???????<div class="navbar-header"> ???????????<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> ???????????????<span class="sr-only">Toggle navigation</span> ???????????????<span class="icon-bar"></span> ???????????????<span class="icon-bar"></span> ???????????????<span class="icon-bar"></span> ???????????</button> ???????????<a class="navbar-brand" href="#">小小相册</a> ???????</div> ???????<!-- Collect the nav links, forms, and other content for toggling --> ???????<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> ???????????<ul class="nav navbar-nav"> ???????????????<li class="active"><a href="/">全部相册 <span class="sr-only">(current)</span></a></li> ???????????????<li><a href="up">上传</a></li> ???????????????<li class="dropdown"> ???????????????????<ul class="dropdown-menu"> ???????????????????????<li><a href="#">Action</a></li> ???????????????????????<li><a href="#">Another action</a></li> ???????????????????????<li><a href="#">Something else here</a></li> ???????????????????????<li role="separator" class="divider"></li> ???????????????????????<li><a href="#">Separated link</a></li> ???????????????????????<li role="separator" class="divider"></li> ???????????????????????<li><a href="#">One more separated link</a></li> ???????????????????</ul> ???????????????</li> ???????????</ul> ???????</div><!-- /.navbar-collapse --> ???</div><!-- /.container-fluid --></nav><div class="container"> ???<img src="/images/404.jpg" ></div><!--运行之后views和public是在一起的--><script src="/js/jquery-1.11.3.min.js"></script><script src="/js/bootstrap.min.js"></script></body></html>

注意上传模块用的formidable,获得的files,fields对象参数,是和表单标签样式name属性对应的。

Node 实现一个MVC相册资源管理器

原文地址:http://www.cnblogs.com/zhangmingzhao/p/7868421.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved