亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

nodejs教程之制作一個簡單的文章發布系統

2019-11-20 13:53:49
字體:
來源:轉載
供稿:網友

前言

我們今天就來做一個簡單的新聞發布系統,系統第一階段不需要太難,主要有以下功能

① 新聞類型管理

② 新聞管理(具有圖片上傳功能)

③ 新聞瀏覽

功能雖然不多,但是也涵蓋很多基本操作了,程序不過增刪查改嘛,外加上傳附件,夠了。于是開始我們今天的學習吧

準備工作

根據昨天的折騰后,我們已經有了nodeJS與mongoDB環境了,現在直接新建工程文件與數據庫文件即可

第一步,打開命令符切換到D盤后輸入

復制代碼 代碼如下:
D:/>express -e news

于是系統會自動開開心心構建基本環境

很明顯,里面很多模塊依賴沒有,這個時候將昨天的package.json直接考過來:

復制代碼 代碼如下:

{
  "name": "application-name",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "3.4.8",
    "ejs": "*",
    "mongodb": "*"
  }
}

然后切換到項目目錄下:

復制代碼 代碼如下:
nmp install

依賴文件全部搞下來了,然后我們輸入

復制代碼 代碼如下:

D:/news>node app
Express server listening on port 3000

于是,我們的程序高高興興的運行起來了,打開網址一看,確實沒問題

PS:這里有個問題需要注意,我們下載下來的文件不是UTF-8編碼,所以中文可能有亂碼,文件編碼需要各位自己統一

程序跑起來了就需要數據庫相關的配置了

① 首先在mongoDB目錄中新建news文件夾

② 為項目新增配置文件settings.js

復制代碼 代碼如下:

module.exports = {
  cookieSecret: 'myNews',
  db: 'news',
  host: 'localhost'
};

③ 新建models目錄,新建db.js

復制代碼 代碼如下:

var settings = require('../settings'),
    Db = require('mongodb').Db,
    Connection = require('mongodb').Connection,
    Server = require('mongodb').Server;
module.exports = new Db(settings.db, new Server(settings.host, Connection.DEFAULT_PORT), { safe: true });

④ 在桌面新建news.bat程序

復制代碼 代碼如下:
d:/mongodb/bin/mongod.exe -dbpath d:/mongodb/news

以后要啟動數據庫,只需要運行他即可,如此,我們初步的準備工作基本結束

但是這里有兩個比較煩的事情,一個是每次要啟動news程序很煩,二個是修改任何東西都需要重啟,于是我們這里先解決這兩個問題

① 在桌面新建news_app.bat,以后運行他就可以啟動程序了

復制代碼 代碼如下:
node d:/news/app

② supervisor為一進程保護程序,我們可以使用他幫我們重啟程序,首先按照,然后調整我們的node_app.bat

復制代碼 代碼如下:
supervisor d:/news/app

當然之前需要安裝:

復制代碼 代碼如下:
npm install -g supervisor

這個樣子后,修改了文件就不需要手動重啟了(需要將news_app放到項目目錄下),于是準備工作到此為止

項目結構

第一步結束后,我們就需要思考下項目結構了

① 首頁為index這里將列出所有新聞類型以及對于新聞條目

② 各個新聞條目擁有編輯/刪除/查看 三個按鈕

③ 首頁具有增加新聞按鈕(增加時候可上傳圖片)

基本功能如上

于是,我們去掉app里面的路由功能,將路由全部放到index里面

復制代碼 代碼如下:

//將路由功能放入index
//app.get('/', routes.index);
//app.get('/users', user.list);
routes(app);

復制代碼 代碼如下:

module.exports = function (app) {
  //主頁,現在也是首頁
  app.get('/', function (req, res) {
    res.render('index', { title: 'Express' });
  });
  app.get('/add', function (req, res) {
    res.send('增加新聞請求');
  });
  app.get('/delete', function (req, res) {
    res.send('刪除新聞請求');
  });
  app.get('/view', function (req, res) {
    res.send('查看新聞請求');
  });
  app.get('/update', function (req, res) {
    res.send('修改新聞請求');
  });
};

第一步簡單如此,因為增加新聞應該有單獨的頁面,而具體點擊增加按鈕又會有其他處理,所以內部還得細分各個請求,現在規定如下:

/ 默認頁面,該頁面顯示所有類型以及新聞,并帶有刪除按鈕

/add 進入添加新聞頁面

/addNews 添加新聞具體post請求地址(點擊按鈕時候的響應)

/delete 刪除新聞請求

/view 具體新聞查詢

于是稍微修改下上述路由:

復制代碼 代碼如下:

module.exports = function (app) {
  //主頁,現在也是首頁
  app.get('/', function (req, res) {
    res.render('index', { title: 'Express' });
  });
  app.get('/add', function (req, res) {
    res.send('添加新聞頁面');
  });
  app.post('/addNews', function (req, res) {
    res.send('處理添加新聞請求');
  });
  app.get('/delete', function (req, res) {
    res.send('刪除新聞請求');
  });
  app.get('/view', function (req, res) {
    res.send('查看新聞請求');
  });
};

于是我們需要新建幾個模板組織我們的網頁,這里我們先不分離頭尾只要最簡單的頁面即可

新增add與view兩個模板文件,暫時表現與index.ejs一致,并且修改導航相關

復制代碼 代碼如下:

module.exports = function (app) {
  //主頁,現在也是首頁
  app.get('/', function (req, res) {
    res.render('index', { title: 'Express' });
  });
  app.get('/add', function (req, res) {
    res.render('add', { title: '添加新聞頁面' });
  });
  app.post('/addNews', function (req, res) {
    res.send('處理添加新聞請求');
  });
  app.get('/delete', function (req, res) {
    res.send('刪除新聞請求');
  });
  app.get('/view', function (req, res) {
    res.render('view', { title: '查看新聞請求' });
  });
};

至此項目結構結束

數據操作

整體結構出來后,我們就需要進行數據操作了:

① 增加數據(增加新聞)

② 展示數據(展示新聞)

③ 刪除數據(刪除新聞)

本來還涉及到類型操作的,但是做著做著給搞沒了,暫時不管他吧,因為首次做容易迷糊

增加新聞

這里,我們就不使用表單提交了,我們用ajax......這里順便引入zepto庫,于是我們的頁面成了這樣

復制代碼 代碼如下:

<!DOCTYPE html>
<html>
<head>
    <title>
        <%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
    <script src="javascripts/zepto.js" type="text/javascript"></script>
</head>
<body>
    <h1>
        <%= title %></h1>
    <div>
        標題:<input type="text" id="title" />
    </div>
    <div>
        內容:<textarea id="content"></textarea>
    </div>
    <div>
        <input type="button" type="button" id="ok" value="添加新聞" />
    </div>
    <script type="text/javascript">
        $(document).ready(function () {
            $('#ok').click(function () {
                var param = {};
                param.title = $('#title').val();
                param.content = $('#content').val();
                $.post('/addNews', param, function () {
                    console.log('添加成功');
                });
            });
        });
    </script>
</body>
</html>

雖然現在還沒有請求響應程序,所以數據并不會被處理,另外我們這里的附件也沒有(現在附件只允許一個好了),于是再修改下代碼,加入圖片:

PS:比較麻煩的是圖片經過ajax處理有點麻煩,所以我們這里乖乖的換回form操作算了,不然又要搞多久......

復制代碼 代碼如下:

<html>
<head>
    <title>
        <%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
    <h1>
        <%= title %></h1>
    <form enctype="multipart/form-data" method="post"  action="/addNews">
    <div>
        標題:<input type="text" id="title" name="title" />
    </div>
    <div>
        圖片:<input type="file" id="pic" name="pic" />
    </div>
    <div>
        內容:<textarea id="content" name="content"></textarea>
    </div>
    <div>
        <input  type="submit" id="ok" value="添加新聞" />
    </div>
    </form>
</body>
</html>

這個樣子就不需要過多的考慮附件問題,先暫時如此吧,現在先處理請求程序,這里先在public里面新建news文件夾用于存儲其圖片

model

在models文件夾新增news.js文件,為其構建實體,并賦予新增查詢相關操作:

復制代碼 代碼如下:

var mongodb = require('./db');

function News(title, content, pic) {
  this.title = title;
  this.content = content;
  this.pic = pic;//保存存儲路徑
};
module.exports = News;
//存儲數據
News.prototype = {
  save: function (callback) {
    var date = new Date();
    var time = {
      date: date,
      year: date.getFullYear(),
      month: date.getFullYear() + "-" + (date.getMonth() + 1),
      day: date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate(),
      minute: date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " +
      date.getHours() + ":" + (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes())
    }
    //數據存儲對象
    var news = {
      title: this.title,
      content: this.content,
      pic: this.pic, //圖片處理最后來說,現在先亂存
      time: time
    };
    //打開數據連接,打開就是一個回調......
    mongodb.open(function (err, db) {
      //錯誤就退出
      if (err) {
        return callback(err);
      }
      //打開news集合
      db.collection('news', function (err, collection) {
        if (err) {
          mongodb.close();
          return callback(err);
        }
        //寫入集合(寫入數據庫)
        collection.insert(news, { safe: true }, function (err) {
          return callback(err);
        });
        callback(null);//err為null
      });
    });
  }
};

于是,寫入數據庫的程序就有了,這里我們來試試能不能插入數據庫,當然需要修改路由處的程序

PS:路由處當然不能寫過多邏輯代碼,這個文件以后還得分離

這個時候/addNews里面的邏輯需要改變

復制代碼 代碼如下:

app.post('/addNews', function (req, res) {
  var title = req.body.title;
  var content = req.body.content;
  var pic = req.body.pic;
  var news = new News(title, content, pic)
  news.save(function (err, data) {
    res.send(data);
  })
});

查詢下,問題不大,現在要解決的就是附件問題了

上傳圖片

上傳圖片功能express本身就支持了,express通過bodyParser解析請求體,然后便可通過他上傳文件了,其內部使用了formidable

這里將app.js里面的app.use(express.bodyParser())改為:

復制代碼 代碼如下:
app.use(express.bodyParser({ keepExtensions: true, uploadDir: './public/news' }));

打開index.js,在前面加一行代碼:

復制代碼 代碼如下:
fs = require('fs'),

修改一下index文件:

復制代碼 代碼如下:

app.post('/addNews', function (req, res) {
  for (var i in req.files) {
    if (req.files[i] == 0) {
      //同步方式刪除一個文件
      fs.unlinkSync(req.files[i].path);
      console.log('success removed an empty file');
    } else {
      var path = './public/news/' + req.files[i].name;
      // 使用同步方式重命名一個文件
      fs.renameSync(req.files[i].path, path);
      console.log('sunccess renamed a file');
    }
  }
//    var title = req.body.title;
//    var content = req.body.content;
//    var pic = req.body.pic;
//    var news = new News(title, content, pic)
//    news.save(function (err, data) {
//      res.send(data);
//    })
});

這個時候選取文件后點擊添加新聞,我們的文件就上傳上去了

這個時候,我只需要將文件名記錄在數據庫即可,文件目錄里面就有圖片了

復制代碼 代碼如下:

app.post('/addNews', function (req, res) {
  var pic = null;
  for (var i in req.files) {
    if (req.files[i] == 0) {
      //同步方式刪除一個文件
      fs.unlinkSync(req.files[i].path);
      console.log('success removed an empty file');
    } else {
      var path = './public/news/' + req.files[i].name;
      // 使用同步方式重命名一個文件
      fs.renameSync(req.files[i].path, path);
      console.log('sunccess renamed a file');
    }
    pic = req.files[i].name;
  }
  var title = req.body.title;
  var content = req.body.content;
  var news = new News(title, content, pic)
  news.save(function (err, data) {
    res.send(data);
  })
  res.send('<a href="./">請求成功,返回首頁</a>');
});

數據庫中有數據了,我們目錄也有文件了,現在只需要將數據讀出來了

PS:放假兄弟們催的兇,要出去喝酒了

讀取數據

第二步當然是讀取數據,首先是首頁的數據讀取:

復制代碼 代碼如下:

var mongodb = require('./db');
function News(title, content, pic) {
  this.title = title;
  this.content = content;
  this.pic = pic;//保存存儲路徑
};
module.exports = News;
//存儲數據
News.prototype = {
  save: function (callback) {
    var date = new Date();
    //數據存儲對象
    var news = {
      title: this.title,
      content: this.content,
      pic: this.pic, //圖片處理最后來說,現在先亂存
      date: date
    };
    //打開數據連接,打開就是一個回調......
    mongodb.open(function (err, db) {
      //錯誤就退出
      if (err) {
        return callback(err);
      }
      //打開news集合
      db.collection('news', function (err, collection) {
        if (err) {
          mongodb.close();
          return callback(err);
        }
        //寫入集合(寫入數據庫)
        collection.insert(news, { safe: true }, function (err) {
          return callback(err);
        });
        callback(null); //err為null
      });
    });
  }
};
//讀取文章及其相關信息
News.get = function (id, callback) {
  //打開數據庫
  mongodb.open(function (err, db) {
    if (err) {
      return callback(err);
    }
    db.collection('news', function (err, collection) {
      if (err) {
        mongodb.close();
        return callback(err);
      }
      var query = {};
      if (id) {
        query.id = id;
      }
      //根據 query 對象查詢文章
      collection.find(query).sort({
        date: -1
      }).toArray(function (err, data) {
        mongodb.close();
        if (err) {
          return callback(err); //失?。》祷?err
        }
        callback(null, data); //成功!以數組形式返回查詢的結果
      });
    });
  });
};
news.js

復制代碼 代碼如下:

<!DOCTYPE html>
<html>
<head>
    <title>
        <%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
    <h1>
        <%= title %></h1>
    <ul>
        <%for(var k in data) { %>
        <li>
            <div>
               標題: <%=data[k].title %></div>
            <div>
              內容:  <%=data[k].content%></div>
              <div>
              附件:<img src="news/<%= data[k].pic%>" /></div>
              </div>
              <div>
              <a href="/delete?id=<%=data[k] %>">刪除</a>
              </div>
              <hr/>
        </li>
        <%} %>
    </ul>
</body>
</html>

結語

好了,文章發布系統的制作就先到這里了,以后我們再慢慢增加功能,慢慢做美化。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人www视频在线观看| 国产精品99导航| 色偷偷偷综合中文字幕;dd| 国产精品嫩草视频| 久久夜色撩人精品| 国产精品网站大全| 国产精品99久久久久久久久| 国产成人在线亚洲欧美| 久久久久久久999精品视频| 国产日韩精品电影| 欧美激情奇米色| 亚洲国产高潮在线观看| 日韩在线观看网址| 亚洲黄色片网站| 国产区亚洲区欧美区| 亚洲自拍小视频免费观看| 欧美成人四级hd版| 亚洲影院在线看| 国产精品手机播放| 欧美日韩一区免费| 国产在线精品一区免费香蕉| 亚洲欧洲一区二区三区久久| 欧美激情久久久久久| 国产精品日韩电影| 伊人久久久久久久久久久久久| 亚洲成色777777在线观看影院| 91av免费观看91av精品在线| 在线视频精品一| 欧美洲成人男女午夜视频| 日韩二区三区在线| 欧美一区第一页| 亚洲国内高清视频| 日韩综合中文字幕| 日韩欧美一区二区三区久久| 超碰91人人草人人干| 久久精品国亚洲| 欧美国产视频一区二区| 日本亚洲欧美三级| 中文字幕免费精品一区高清| 欧美性猛交xxx| 亚洲女人天堂成人av在线| 国产欧美一区二区三区四区| 日韩欧美大尺度| 日本亚洲精品在线观看| 国产精品99久久久久久人| 一区二区三区视频免费| 精品色蜜蜜精品视频在线观看| 中文字幕日韩在线视频| 国产噜噜噜噜噜久久久久久久久| 国产精品91久久| 日韩在线精品视频| 久久久久久九九九| 欧美精品久久一区二区| 久久精品国产欧美亚洲人人爽| 亚洲精品在线看| 精品久久久久久亚洲国产300| 国产91亚洲精品| 久久久精品一区二区三区| 国产免费一区二区三区在线观看| 国产精品中文字幕在线| 亚洲成人xxx| 成人免费xxxxx在线观看| 91国内在线视频| 日韩一区二区三区国产| 亚洲欧美日韩高清| 中文字幕精品www乱入免费视频| 日韩精品视频中文在线观看| 欧美性精品220| 成人在线视频网| 国产亚洲a∨片在线观看| 欧美黑人xxx| 亚洲精品自在久久| 久久香蕉精品香蕉| 亚洲电影免费观看高清完整版| 亚洲视频在线视频| 日韩电影视频免费| 国产精品电影在线观看| 美女国内精品自产拍在线播放| 在线a欧美视频| 日韩麻豆第一页| 久久在线精品视频| 国产午夜一区二区| 国产一区二区色| 欧美日韩国产123| 欧美激情免费看| 欧美日韩精品在线视频| 亚洲天堂av在线免费观看| 91av在线播放视频| 国产亚洲视频中文字幕视频| 日韩激情片免费| 欧美大片网站在线观看| 亚洲午夜精品久久久久久性色| 欧美大成色www永久网站婷| 国产日韩欧美一二三区| 亚洲欧美制服中文字幕| 色999日韩欧美国产| 国产91ⅴ在线精品免费观看| 国产美女久久精品香蕉69| 亚洲国产成人在线视频| 欧美成人网在线| 亚洲欧美中文在线视频| 国产精品一区二区三区免费视频| 成人亲热视频网站| 久久久综合免费视频| 欧美激情一二区| 亚洲男人的天堂在线| 国产精品吊钟奶在线| 久久艳片www.17c.com| 高清日韩电视剧大全免费播放在线观看| 亚洲一区亚洲二区| 少妇高潮久久久久久潘金莲| 日韩精品视频在线观看免费| 久久视频在线观看免费| 国产91精品久久久| 91在线精品视频| 欧美性猛交xxxx乱大交3| 韩剧1988在线观看免费完整版| 精品亚洲精品福利线在观看| 一区二区三区高清国产| 91成人精品网站| 亚洲国产日韩一区| 日本亚洲欧洲色α| 66m—66摸成人免费视频| 国产精品一区二区三区久久| 久热精品视频在线| 亚洲精品一区二区久| 成人国产精品色哟哟| 91亚洲精品一区二区| 亚洲毛片在线免费观看| 91sa在线看| 国产亚洲人成a一在线v站| 欧美一级高清免费| 98午夜经典影视| 亚洲精品99久久久久中文字幕| 亚洲第一精品电影| 国产日韩欧美在线视频观看| 国产日韩中文在线| 日韩精品欧美激情| 亚洲在线观看视频网站| 国产精品久久久久久av福利软件| 成人激情免费在线| 疯狂欧美牲乱大交777| 久久久久久国产精品三级玉女聊斋| 韩日欧美一区二区| 日韩av电影在线网| 亚洲欧美国产精品久久久久久久| 日韩网站在线观看| 国产精品极品在线| 国产精品一区二区电影| 久久精品国产亚洲精品| 色与欲影视天天看综合网| 国产精品91久久久| 亚洲iv一区二区三区| 98精品在线视频| 国产精品亚洲一区二区三区| 久久久亚洲天堂| 国产丝袜一区二区| 影音先锋欧美在线资源| 社区色欧美激情 | 亚洲精品一区二区在线| 九九热这里只有精品6| 中文字幕免费精品一区高清| 亚洲成人aaa| 亚洲资源在线看|