新手向:相冊demo

代碼地址哦css

首頁

目錄結構

  • controller ——控制器層html

  • models ——數據層node

  • node_modules ——依賴包文件jquery

  • public ——靜態文件目錄git

  • uploads ——上傳文件保存目錄github

  • tempup ——臨時緩存文件express

  • views ——顯示層npm

  • app.js ——住文件入口json

  • package.json ——配置文件bootstrap

1.第一步

新建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"
}

2.啓動express模塊

寫入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端口成功");
});

3.設置首頁路由

向app.js裏面添加

// 引入控制器
var router = require('./controller');

// 設置路由
// --首頁
app.get('/', router.showIndex);

router.showIndex是渲染控制器方法

4.添加控制器

向controller文件夾下添加router.js文件,且設置配置文件,package.json 設置默認入口爲router.js不然默認index.js

package.json
{
    "main": "router.js"
}
router.js
// 設置首頁模板渲染方法
exports.showIndex = function(req,res,next) {

}

這裏須要去文件夾拿照片 因此去models文件夾下新增file.js

5.設置models層

新建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);
    });
}

6.router中引用models

修改router文件,

controller/router.js
// 引入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 運行看一下效果吧==

相冊內頁

1.添加路由

app.js
// --首頁點擊相冊內頁
app.get('/:albumName',router.showAlbum);

2.controller層添加控制器

controller/router
// 相冊頁
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
        });
    });
}

3.view層添加模板

views/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>小小相冊</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>

4.把uploads內加入靜態資源

app.js
// 讓存圖片的文件夾也能訪問
app.use(express.static('./uploads'));

==node app.js跑一下看下吧==

上傳頁

1.路由

app.js
// --上傳頁面路由,接收頁
app.get('/up', router.showUp);

2.controller添加控制器

controller/router.js
// 上傳接收頁
exports.showUp = function(req, res, next) {
    // 獲取全部文件夾名稱
    file.getAllAlbums(function(err, albums) {
        // 渲染up頁面
        res.render('up', {
            albums: albums
        });
    });
}

3.view層添加模板

這裏循環拿到的文件夾名稱數組albums

form提交 enctype="multipart/form-data" 要改爲這個

views/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">
</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 看下吧 ~

接收上傳文件

1.路由

app.js
// --接收上傳文件
app.post('/up', router.doPost);

2.controller層

向router裏面添加方法

controller/router.js
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;
}

==運行下上傳個圖片看看效果吧==

相關文章
相關標籤/搜索