代碼地址哦css
controller ——控制器層html
models ——數據層node
node_modules ——依賴包文件jquery
public ——靜態文件目錄git
uploads ——上傳文件保存目錄github
tempup ——臨時緩存文件express
views ——顯示層npm
app.js ——住文件入口json
package.json ——配置文件bootstrap
新建package.json文件,並執行npm install 安裝依賴包文件,而後新建各個文件夾。
{ "name": "little-album", "version": "1.0.0", "description": "", "main": "app.js", "dependencies": { "ejs": "^2.3.4", "express": "^4.13.3", "formidable": "^1.0.17", "silly-datetime": "^0.1.2" }, "devDependencies": {}, "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
寫入app.js,而且node app.js啓動看看
// 引入express框架 var express = require('express'); // 註冊express var app = express(); // 設置模板引擎ejs app.set('view engine', 'ejs'); // 設置靜態資源路徑 app.use(express.static("./public")); // 監聽端口 app.listen(3004, function() { console.log("啓動3004端口成功"); });
向app.js裏面添加
// 引入控制器 var router = require('./controller'); // 設置路由 // --首頁 app.get('/', router.showIndex);
router.showIndex是渲染控制器方法
向controller文件夾下添加router.js文件,且設置配置文件,package.json 設置默認入口爲router.js不然默認index.js
{ "main": "router.js" }
// 設置首頁模板渲染方法 exports.showIndex = function(req,res,next) { }
這裏須要去文件夾拿照片 因此去models文件夾下新增file.js
新建file.js,寫入查找文件的遍歷方法
// 引入fs模塊 var fs = require('fs'); // callback(err,date); // 找到uploads下全部文件夾 exports.getAllAlbums = function(callback) { // 讀取文件夾內全部文件夾名字 fs.readdir('./uploads', function(err, files) { // 設置報錯 if (err) { callback('沒有找到uploads文件', 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('沒有找到uploads文件', 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); } // 加入數組 if (stats.isFile()) { allImages.push(files[i]); } // 下一次遍歷 iterator(i + 1); }); })(0); }); }
修改router文件,
// 引入models var file = require('../models/file.js'); // 設置首頁模板渲染方法 exports.showIndex = function(req, res, next) { // 找到upload下面全部文件夾名 file.getAllAlbums(function(err, allAlabums) { if (err) { // 交給下面的中間件 next(); return; } // 渲染模板,引用views裏index模板 res.render('index', { 'albums': allAlabums }); }); }
而且在views文件夾下新增index.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"> <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> </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/wjj.jpg" alt="..."> </a> <h4><%= albums[i] %></h4> </div> <% } %> </div> </div> <script src="js/jquery-1.11.3.min.js"></script> <script src="js/bootstrap.min.js"></script> </body> </html>
在public文件夾下加入images文件夾且引入wjj.jpg圖片文件
==在uploads下面新建幾個文件夾 node app.js 運行看一下效果吧==
// --首頁點擊相冊內頁 app.get('/:albumName',router.showAlbum);
// 相冊頁 exports.showAlbum = function(req, res, next) { // 從url上拿到albumName字段 var albumName = req.params.albumName; // 交給models處理拿到images名字列表 file.getAllImagesByAlbumName(albumName, function(err, imagesArray) { if (err) { next(); return; } // 渲染album模板 res.render('album', { 'albumname' : albumName, 'images' : imagesArray }); }); }
<!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"> <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><a href="/">所有相冊<span class="sr-only">(current)</span></a></li> <li><a href="/up">上傳</a></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]%>" alt="..."> </a> <h4> </h4> </div> <%}%> </div> </div> <script src="/js/jquery-1.11.3.min.js"></script> <script src="/js/bootstrap.min.js"></script> </body> </html>
// 讓存圖片的文件夾也能訪問 app.use(express.static('./uploads'));
==node app.js跑一下看下吧==
// --上傳頁面路由,接收頁 app.get('/up', router.showUp);
// 上傳接收頁 exports.showUp = function(req, res, next) { // 獲取全部文件夾名稱 file.getAllAlbums(function(err, albums) { // 渲染up頁面 res.render('up', { albums: albums }); }); }
這裏循環拿到的文件夾名稱數組albums
form提交 enctype="multipart/form-data" 要改爲這個
<!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"> </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><a href="#">所有相冊<span class="sr-only">(current)</span></a></li> <li><a href="#">上傳</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <div class="container"> <div class="row"> <!-- form 必須改成multipart/form-data 才能拿到文件 --> <form style="width:40%;" method="post" action="#" enctype="multipart/form-data"> <div class="form-group"> <label for="exampleInputEmail1">選擇文件夾</label> <!-- 循環拿到的albums文件夾名數組 --> <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"> </div> <button type="submit" class="btn btn-default">上傳</button> </form> </div> </div> <script src="/js/jquery-1.11.3.min.js"></script> <script src="/js/bootstrap.min.js"></script> </body> </html>
ok啦 訪問 /up 看下吧 ~
// --接收上傳文件 app.post('/up', router.doPost);
向router裏面添加方法
var fs = require('fs'); var sd = require('silly-datetime'); var path = require('path'); // 上傳表單 exports.doPost = function(req, res, next) { // 使用 formidable 處理form 提交表單 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; } // 尺寸過大刪除 // tupian 是html裏面name設置的 var size = parseInt(files.tupian.size); if (size > 2000) { res.send('圖片尺寸應該小魚1M'); // 刪除緩存圖片 這裏要用到fs模塊 fs.unlink(files.tupian.path); return; } // 接下來更名字 // 獲取時間戳 var ttt = sd.format(new Date(), 'YYYYMMDDHHmmss'); // 獲取隨機數 var ran = parseInt(Math.random() * 89999 + 10000); // 獲取上傳的文件名 var extname = path.extname(files.tupian.name); // 獲取文件夾名字 var wenjianjia = fields.wenjianjia; // 緩存的文件路勁 var oldpath = files.tupian.path; // 存下來的路徑 var newpath = path.normalize(__dirname + '/../uploads/' + wenjianjia + '/' + ttt + ran + extname); // 更名字 fs.rename(oldpath, newpath, function(err) { if (err) { res.send('更名失敗'); return; } res.send('成功') }); }); return; }
==運行下上傳個圖片看看效果吧==