我用Node.js + Express + MongoDB创建了一款文章管理应用程序

简要概述

記事を投稿、管理できるアプリを作成した。機能としては、アカウント登録、ログイン機能、記事作成&編集&削除機能がある。見た目は以下のようになる。

外貌

外观如下所示。

1.png
2.png
3.png
4.png
5.png

源代码

我把源代码上传到了GitHub上。
https://github.com/akikisai/Article-management-app

使用过的库

以下是使用的工具和版本。

使用的物品和版本如下。

“cookie-parser”: “~1.4.4” -> “cookie-parser”: “~1.4.4”,
“debug”: “~2.6.9” -> “debug”: “~2.6.9”,
“ejs”: “~2.6.1” -> “ejs”: “~2.6.1”,
“express”: “~4.16.1” -> “express”: “~4.16.1”,
“express-session”: “^1.17.2” -> “express-session”: “^1.17.2”,
“http-errors”: “~1.6.3” -> “http-errors”: “~1.6.3”,
“moment”: “^2.29.1” -> “moment”: “^2.29.1”,
“mongodb”: “^4.4.0” -> “mongodb”: “^4.4.0”,
“morgan”: “~1.9.1” -> “morgan”: “~1.9.1”

搭建环境

首先进行环境搭建。

建立node.js环境

请从以下链接下载并安装node.js的推荐版本,按照安装程序的流程进行安装,无需进行任何修改。这样就可以使用npm命令了。
node.js下载站点。

構建MongoDB環境

根据以下链接的内容进行环境配置。
进行MongoDB环境配置。

如果输入mongo命令后出现mongo shell,则表示成功。

创建项目

我想在桌面上创建一个项目。首先使用cd命令进行移动,并安装express,以便能够快速创建应用程序。

$ cd Desktop
$ npm install express-generator -g

创建一个名为textapp的项目。这时候在桌面上会创建一个textapp文件夹。
然后进入textapp文件夹,使用npm install命令安装初始的软件包,以便可以使用它们。

$ express -e textapp
$ cd textapp
$ npm install

如果没有文本编辑器,建议使用Visual Studio Code或Atom。
Visual Studio Code官方网站
Atom官方网站

在Node.js中,为了使更改生效,需要重新启动进程,但使用nodemon可以自动重新启动进程,从而消除额外的步骤。请安装nodemon。

$ npm install nodemon -g

将package.json文件中的”start”: “node ./bin/www”修改为以下内容,以支持nodemon。

"start": "nodemon ./bin/www"

用npm start命令启动项目。

$ npm start

在文件中,我们可以看到端口被设置为3000,
bin文件 > www文件 > var port = normalizePort(process.env.PORT || ‘3000’);
当我们在网站上输入以下链接时,
http://localhost:3000/
显示”欢迎使用express”。
在这里需要注意的是,在进行下一步操作时,请不要关闭输入npm start的终端。

连接到MongoDB

MongoDB的环境已经设置好了,在这里打开一个新的git bash,使用以下命令来确定数据库的存储位置。在这个例子中,将其保存在C:\mongodb\data中。

$ mongod --dbpath "C:\mongodb\data"

要连接到MongoDB,需要同时存在输入npm start命令的shell和打开的mongo shell。若存在已经打开的mongo shell表示成功连接到MongoDB。另外,如果在终端无法成功输入mongo shell命令,可以尝试使用Windows的命令提示符。

$ mongo

能够与MongoDB连接并使用shell。

确认数据库的内容

>show dbs 

默认情况下如下所示。

admin   0.000GB
config  0.000GB
local   0.000GB

使用textapp来创建数据库。

创建用户集合。
db.createCollection(‘users’);

展示收藏品。

MongoDB 命令供参考使用。

为了连接Node.js和MongoDB,可以使用MongoDB Node.js驱动程序。
※另外还有使用Mongoose的方法,似乎比较受欢迎。

有关安装和使用方法,请参考 MongoDB Node.js 驱动程序文档。

在textapp文件夹中使用cd命令安装mongodb nodejs驱动程序,可以使用以下命令:
cd textapp
npm install mongodb –save

参考ドキュメントの例に従って、MongoDBに接続するためのコードを作成します。ファイルの新規作成などの詳細な手順は省略します(GitHubのソースコードを参照すれば分かるので)。この記事では、主に機能についてまとめたいと思います。

var MongoClient = require('mongodb').MongoClient;

var url = 'mongodb://localhost:27017/textapp';
var dbName = 'textapp';

//データベースへ接続用関数
function connect(callback) {//関数化
  MongoClient.connect(url, function(err, client) {//コールバック関数

	//エラーの場合
    if (err) {
      console.log('データベース接続エラー', err);
	//エラーじゃない場合
    } else {
	//接続成功
      var db = client.db(dbName);
      callback && callback(db);
    }
  });
}


module.exports = {
  connect
}

将连接功能转换为函数,并使其可以在之后使用。

注册和登录

进行路由设置。

// 登録ページ
router.get('/regist', function(req, res, next) {
  res.render('regist', {})
});

// ログインページ
router.get('/login', function(req, res, next) {
  res.render('login', {})
});

注册页面的代码将如下所示。

<body>

  <div class="container">
	   <div class="login-container">
            <div class="form-box">
                <form action="/users/regist" method="post">
                  <input type="text" name="username" value="" placeholder="ユーザ名">
                  <input type="password" name="password" value="" placeholder="パスワード">
                    <button class="btn btn-info btn-block login" type="submit">登録する</button>
                </form>
                <div>アカウントをお持ちの場合、<br><a href="/login">ログイン</a>してください。</div>
            </div>
      </div>
  </div>

</body>

这将导致用户名和密码被发送到”/users/regist”。

// 登録
router.post('/regist', function(req, res, next) {
  var data = {
    username: req.body.username,
    password: req.body.password
  };


  // データの接続
  model.connect(function(db) {
    //コレクションusersにデータ挿入する
    db.collection('users').insertOne(data, function(err, ret) {
      //登録失敗
      if (err) {
        console.log('登録失敗');
        res.redirect('/regist');
      } else {
        //登録成功、ログインページへ
        res.redirect('/login');
      }
    });
  })
})

收到的信息会存储在数据中,并连接到数据库进行验证,以确定是否成功注册。如果安装了MongoDB和MongoDB Compass,可以打开MongoDB Compass并点击连接按钮,即可连接到MongoDB,并在图形界面上确认已注册的信息是否存在。可参考使用MongoDB Compass。

ログインページのコードは以下のようになる。

<body>

  <div class="container">
	<div class="login-container">

            <div class="form-box">
                <form action="/users/login" method="post">
                    <input name="username" type="text" placeholder="ユーザ名">
                    <input name="password" type="password" placeholder="パスワード">
                    <button class="btn btn-info btn-block login" type="submit">ログイン</button>
                </form>
                <div>アカウントをお持ちでない場合<a href="/regist">作成</a>できます。</div>

            </div>
        </div>

</div>

</body>

これにより、ユーザ名とパスワードは”/users/login”へ送信される。

// ログイン
router.post('/login', function(req, res, next) {
  var data = {
    username: req.body.username,
    password: req.body.password
  }

  //データベースに接続する。
  model.connect(function(db) {
    //コレクションに同じデータがあるか、あればログイン成功。
    db.collection('users').find(data).toArray(function(err, docs) {
      if (err) {
		//ログイン失敗→もう一回ログインページへ
        res.redirect('/login');
      }else {
	  //調べたdocsの結果が0以上であれば成功
        if (docs.length > 0) {
          // ログイン成功 session保存
          req.session.username = data.username;//ユーザーネームをセッションに保存
          res.redirect('/');
        } else {
          res.redirect('/login');
        }
      }
    })
  })
})

送信されてきた情報はdataに格納され、データベースに接続し、照らし合わせることでログイン成功か失敗か。失敗したらもう一度ログインページへ行く。また、上のコードでsessionを使用している。これはログイン状態を保存するため(毎回ログインするのはめんどくさいので)

首先,在textapp文件夹中安装express-session以使用session。请执行以下命令。使用方法请参考express-session文档。

$ npm install express-session -S

首先进行设置。

var session = require('express-session');

//セッション
app.use(session({
  secret: 'sai textapp',//何でもよい
  resave: false,
  saveUninitialized: true,
  cookie: { maxAge: 1000 * 60 * 20 } //cookie有効時間=ログイン有効期間
}))

ここでのログイン有効期間を20分とした。また上のログインが成功した場合ユーザ名をsessionに格納される。もしsessionにユーザ名がある場合、ログインせずにホームぺーズへ飛ぶことができるようになる。ユーザ名がニア場合、かつログインページと登録ページ以外ならば、ログインページへ戻る。これでログインしていない状態だとホームページは見れない。

// sessionの中身判定
app.get('*', function(req, res, next) {
  var username = req.session.username;
  //パスを判断したいので宣言
  var path = req.path;
  
  //ログインページと登録ページ以外で、ユーザ名なければログインページへ飛ぶ。
  if (path != '/login' && path != '/regist') {
    if (!username) {
      res.redirect('/login');
    }
  }
  next();
})

ログアウト

将发布按钮和注销按钮放置在标题栏上。

<li class="header_navi_item"><a href="/users/logout"><span>ログアウト</span></a></li>

ログアウトするには簡単で、sessionの中身を空っぽにしてlogin画面へ飛べばよい。

//ログアウト
router.get('/logout',function(req,res,next){
  req.session.username = null;
  res.redirect('/login');
})

发表文章

ホームページに投稿するボタンを用意する。投稿画面/writeへ飛ぶ。

<li class="header_navi_item"><a href="/write"><span>投稿する</span></a></li>

创造画面。

<body>

  <%- include('bar', {username: username}) %>
  <div class="article">
    <form action="/article/add" method="post">

      <input type="text" name="title" placeholder="タイトル" value="">
      <textarea name="content" class="xheditor" id="mytextarea"></textarea>

	  <input type="submit" value="投稿">
      
    </form>
  </div>

</body>

然而,在这里的bar是指bar.ejs,并且我们会在这里创建一个标题。由于多个页面都会使用相同的标题,因此我们将其作为一个独立的bar.ejs文件创建,并通过include来调用并使用它。在这种情况下,我们需要在routes/index.ejs的router.get(‘/write’, function(req, res, next) {})中获取username并返回它,因为我们需要求得username。这样一来,我们就可以将username存储在bar(标题)的用户名处,并显示在页面的顶部,就像最上面所显示的一样。

我想在这里实现一个富文本编辑器,以便进行投稿。
富文本编辑器是指可以在不了解HTML的情况下,通过使用工具按钮来创建和编辑文字、图片、表格等内容的工具。实际上,即使将复制的内容粘贴到投稿栏中,格式也会保留。
→ 就像博客投稿时使用的编辑器一样。

今回使用するのはTinyMCEというもの。公式ページの始め方参照はこちら
やや古いですがとても分かりやすいTinyMCE使い方記事はこちら
なお、ほかのリーチテキストエディタを使いたい場合、リッチテキストエディタ一覧を参考して、各自調べてください。

写代码时,请按照文档上的要求进行操作。文档可能会有些陈旧,但一定要参考文档进行操作。按照文档的指示来做,

<script src="https://cdn.tiny.cloud/1/no-api-key/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script>

http://から始まって直接読み込むことができるので便利ですが、今回はTinyMCEを直接ダウンロードページからDownlord TinyMCE SDK nowをクリックし、ダウンロードして解凍して中身のファイルをtextapp/public/javascriptsの中にいれ、リンクは代わりにtinymce.min.jsを適切なパスで読み込む。今回の例では
javascripts/tinymce_5.10.3/tinymce/js/tinymce/
の中に存在する。

修改write.js文件中的head标签,添加了两个script标签。

<head>

  <title>記事作成</title>
  <%- include head %>

  <script src="javascripts/tinymce_5.10.3/tinymce/js/tinymce/tinymce.min.js" referrerpolicy="origin"></script>

   <script>
     tinymce.init({
       selector: 'textarea',
       language: 'ja'
     });
   </script>

</head>

言語を日本語化にしたいので、TinyMCE言語パッケージページからjaを見つけ、ダウンロードする。解凍したlangsフォルダの「ja.js」を「tinymce/」にある「langsフォルダ」へ移動する。
うえのようにlanguage: ‘ja’と記入すれば完成。

我将投稿一篇文章,将新的集合添加到数据库中。
在Mongo Shell中输入以下命令,创建一个名为articles的集合。

use textapp
db.createCollection('articles');

次は実際に記事書いたら、記事を投稿する機能を持つボタンを作る。ここで入力内容はformの/article/addへ行く。ということで作成していく。


// 追加
router.post('/add', function(req, res, next) {
	//データを受け取る
	var data = {
      title: req.body.title,//タイトル
      content: req.body.content,//記事内容
      username: req.session.username,//ユーザ名
      id: Date.now()//時間

	//データベースに接続し、データを挿入する
    model.connect(function(db) {
      db.collection('articles').insertOne(data, function(err, ret) {
        if(err) {
          console.log('文件发布失败', err)
		//失敗、もう一回記事投稿ページ
          res.redirect('/write')
        } else {
		//成功、ホームページへ
          res.redirect('/')
        }
      })
    })
  }
})

正しく入っているかどうか、Mongo shellで確認するか、MongoDB compassで確認する。

新闻显示(网页)

まずroutes/index.jsの”/”へ飛ぶ時の処理を編集する。
時間を扱いたいので、gitbashでtextapp内においてmomentをインストール。
npm install moment -S
公式ドキュメントはこちら

/* ホームページ*/
router.get('/', function(req, res, next) {
  var username = req.session.username;

  //データベース接続
  model.connect(function(db) {
    // すべての記事を調べる。
    db.collection('articles').find().toArray(function(err, docs) {
      var list = docs;
	//ここでマップを使って、時間を表しているidを日付形式に変換し、timeと名付ける。
     list.map(function(ele, index) {
        ele['time'] = moment(ele.id).format('YYYY-MM-DD HH:mm:ss')
     res.render('index', { username: username, data: list });    
    })
  })

});

接下来要创建新闻显示页面。所获取的内容对象中包含了所需的信息。

<% list.map(function(item,index){ %>
        <div class="row">
          <span><%= index+1 %></span>
          <span><%= item.username %></span>
          <span><%= item.title %></span>
			<!-- 定義したtimeを使用している。-->
          <span><%= item.time %></span>
          <span>
            <a href="">編集</a>
            <a href="">削除</a>
          </span>
        </div>
      <% }) %>

文章列表分页

如果有很多篇文章,可以將頁面分開設定每頁可顯示多少篇文章。需要編輯 routes/index.js 和 views/index.js。

/* ホームページ*/
router.get('/', function(req, res, next) {
  var username = req.session.username;
  //フロント側で今は何ページ目にいるかデータを受け取る、なければ1
  var page = req.query.page || 1;
  var data = {
    total: 0,//トータル何ページ必要か
    curPage: page,//現在あるページ数
    list:[]//今表示しているページの記事リスト
  }
  var pageSize = 2;//表示しているページに記事何個ひょうじするか

  model.connect(function(db) {
    // すべての記事を調べる。
    db.collection('articles').find().toArray(function(err, docs) {
      //全部の記事数÷1ぺ時に表示する記事数=トータル何ページ必要か
      //Math.ceil() 関数は、引数として与えた数以上の最小の整数を返す
      data.total = Math.ceil(docs.length / pageSize)
      // 今のページの記事リストを調べる。
      model.connect(function(db) {
        // sort()  limit()  skip()
        //降順で、一回に調べる記事数を限定(2)、スキップする個数(1ページ目なら(1-1)*2で0,スキップせず最初から2つ調べる)
        db.collection('articles').find().sort({_id: -1}).limit(pageSize).skip((page-1)*pageSize).toArray(function(err, docs2) {
          //時間変換
	      docs2.map(function(ele, index) {
            ele['time'] = moment(ele.id).format('YYYY-MM-DD HH:mm:ss')
          })
          data.list = docs2
          res.render('index', { username: username, data: data });
        })
      })
    })
  })

});

在分類文章時需要的信息是

    1. total: トータルで何ページ必要か

 

    1. cuiPage: 現在あるページ数 (ここでは必要ないが後で削除機能のために使う)

 

    1. list: 今表示しているページの記事のリスト

 

    1. page: フロント側で今は何ページ目にいるかデータ

 

    pageSize: 1ページに表示したい記事数

であり、取得した記事数によって、
total =記事数÷pageSize(小数の場合大き目の整数に変換)

<body>
    <%- include('bar', {username}) %>

    <div class="list">
      <!-- ページ分け、何ページ目 -->
      <div class="pages">
        <% for(let i=1; i<=data.total; i++) { %>
		<!-- ここでクリックすると今いる何ページ目かが"/"にわたり、そのページ内容を表示したい-->
          <a class="pages_style" href="/?page=<%= i %>"><%= i %></a>
        <% } %>
      </div>

      <div class="row">
        <span>順番</span>
        <span>作者</span>
        <span>タイトル</span>
        <span>公開日</span>
        <span>
          <i class="fa-solid fa-pen-to-square"></i>
        </span>

      </div>

      <!-- 記事リスト -->
      <% data.list.map(function(item,index){ %>
        <div class="row">
          <span><%= index+1 %></span>
          <span><%= item.username %></span>
          <span><%= item.title %></span>
          <span><%= item.time %></span>
          <span>
            <a href="">編集</a>
            <a href="">削除</a>
          </span>
        </div>
      <% }) %>

    </div>

</body>

使用for循环来利用data.total,以显示实际页面数。此外,将表示当前页码的page传递给页码按钮中的“/”,利用这个信息来选择应该显示的文章,并存储在data.list中。

删除文章

将views/index.js中的删除部分修改如下。
删除所需的信息包括文章的id,以及当前所在的页数,即需要一个page变量。需要注意的是,?id=<%=item.id%>&page=<%=data.curPage%>这部分,?之后是URL参数,并将该值传递给目标位置。

<a href="/article/delete?id=<%=item.id%>&page=<%=data.curPage%>">削除</a>

編輯routes/article.js文件。


// 記事削除
router.get('/delete', function(req, res, next) {
 var id = parseInt(req.query.id)
 var page = req.query.page
 //接続
 model.connect(function(db) {
   //idで調べる
   db.collection('articles').deleteOne({id: id}, function(err, ret) {
     if (err) {
       console.log('削除失敗');
     } else {
       console.log('削除成功');
     }
     //リダイレクトする
     res.redirect('/?page='+page);
   })
 })
})

然而,在这种情况下,即使删除页面中没有任何文章,也可以显示出来,这是不合适的。为了修复这个问题,需要在routes/index.js中添加判断条件。

/* ホームページ*/
router.get('/', function(req, res, next) {
  var username = req.session.username;
  //フロント側で今は何ページ目にいるかデータを受け取る、なければ1
  var page = req.query.page || 1;
  var data = {
    total: 0,//トータル何ページ必要か
    curPage: page,//現在あるページ数
    list:[]//今表示しているページの記事リスト
  }
  var pageSize = 2;//表示しているページに記事何個ひょうじするか

  model.connect(function(db) {
    // すべての記事を調べる。
    db.collection('articles').find().toArray(function(err, docs) {
      //全部の記事数÷1ぺ時に表示する記事数=トータル何ページ必要か
      //Math.ceil() 関数は、引数として与えた数以上の最小の整数を返す
      data.total = Math.ceil(docs.length / pageSize)
      // 今のページの記事リストを調べる。
      model.connect(function(db) {
        // sort()  limit()  skip()
        //降順で、一回に調べる記事数を限定(2)、スキップする個数(1ページ目なら(1-1)*2で0,スキップせず最初から2つ調べる)
        db.collection('articles').find().sort({_id: -1}).limit(pageSize).skip((page-1)*pageSize).toArray(function(err, docs2) {
			//記事がなければ
           if (docs2.length == 0) {
             //前のページに戻る、最小1
             res.redirect('/?page='+((page-1) || 1))
           } else {
		   //記事があれば、時間の処理をする。
            docs2.map(function(ele, index) {
              ele['time'] = moment(ele.id).format('YYYY-MM-DD HH:mm:ss')
            })
            data.list = docs2
           }
          res.render('index', { username: username, data: data });
        })
      })
    })
  })

});

新闻编辑

跳转至write页面。同样需要id和curPage参数。

<a href="/write?id=<%=item.id%>&page=<%=data.curPage%>">編集</a>

以下是以一种方式实现的:

router.get(‘/write’, function(req, res, next) {})

// 投稿&編集ページ
router.get('/write', function(req, res, next) {
  var username = req.session.username || ''
  var id = parseInt(req.query.id)
  var page = req.query.page
  var item = {
    title: '',
    content: ''
  }
  if (id) {  // idがあれば編集
    model.connect(function(db) {
      db.collection('articles').findOne({id: id} , function(err, docs) {
        if (err) {
          console.log('失败')
        } else {
          item = docs
          item['page'] = page
          res.render('write', {username: username, item: item})
        }
      })
    })
  } else {  // idがなければ追加
    res.render('write', {username: username, item: item})
  }
})

此外,还需要对write画面进行编辑。

<body>

  <%- include('bar', {username: username}) %>
  <div class="article">
    <form action="/article/add" method="post">

      <input type="hidden" name="id" value="<%- item.id %>">
      <input type="hidden" name="page" value="<%- item.page %>">
      <input type="text" name="title" placeholder="タイトル" value="<%= item.title %>">
      <textarea name="content" class="xheditor" id="mytextarea"><%- item.content %></textarea>
      <% if (item.id) { %>
        <input type="submit" value="編集">
      <%} else {%>
        <input type="submit" value="投稿">
      <%}%>
    </form>
  </div>

</body>

如果有id,则在按钮上显示“编辑”,否则显示“投稿”。
此外,为了进行编辑,页面和id必须要传入。
编辑成功后,希望跳转到页面。

<input type="hidden" name="id" value="<%- item.id %>">
<input type="hidden" name="page" value="<%- item.page %>">

使用隐藏使其不可见并进行排列。
还需要编辑 /article/add 部分。同样使用id进行编辑。


// 追加、編集
router.post('/add', function(req, res, next) {
  var id = parseInt(req.body.id)
  if (id) {  //編集
    var page = req.body.page
    var title = req.body.title
    var content = req.body.content
    model.connect(function(db) {
      db.collection('articles').updateOne({id: id}, {$set: {
        title: title,
        content: content
      }}, function(err, ret) {
        if (err) {
          console.log('編集失敗', err)
        } else {
          console.log('編集成功')
          res.redirect('/?page='+page)
        }
      })
    })
  } else {   //追加
    var data = {
      title: req.body.title,
      content: req.body.content,
      username: req.session.username,
      id: Date.now()
    }
    model.connect(function(db) {
      db.collection('articles').insertOne(data, function(err, ret) {
        if(err) {
          console.log('失败', err)
          res.redirect('/write')
        } else {
          res.redirect('/')
        }
      })
    })
  }
})

新闻报道

在标题栏处设置目的地。

<span><a href="/detail?id=<%=item.id%>"><%= item.title %></a></span>

创建文章表达页面。

<!DOCTYPE html>
<html lang="ja">
<head>

  <title><%=item.title%></title>
  <%- include head %>
</head>
<body>

  <%- include('bar', {username: username}) %>
  <div class="detail">
    <div class="title"><%=item.title%></div>
    <div class='desc'>
      <span>作者:<%=item.username%></span>
      <span>投稿日:<%=item.time%></span>
    </div>
    <div class="content"><%-item.content%></div>
  </div>

</body>
</html>

也需要在routes/index.js中添加代码。

// 記事詳細ページ
router.get('/detail', function(req, res, next) {
  var id = parseInt(req.query.id)
  var username = req.session.username || ''
  model.connect(function(db) {
    db.collection('articles').findOne({id: id}, function(err, docs) {
      if (err) {
        console.log('失败', err)
      } else {
        var item = docs
        item['time'] = moment(item.id).format('YYYY-MM-DD HH:mm:ss')
        res.render('detail', {item: item, username: username})
      }
    })
  })
})

按下标题后,可以查看相关文章的详细信息。

其他

如果继续这样下去,实际上其他人也可以编辑和删除他人的文章。这是不好的,需要进行改变。方法很简单,只需按照以下方式进行修正即可。

<!-- 記事リスト -->
      <% data.list.map(function(item,index){ %>
        <div class="row">
          <span><%= index+1 %></span>
          <span><%= item.username %></span>
          <span><a href="/detail?id=<%=item.id%>"><%= item.title %></a></span>
          <span><%= item.time %></span>
          <span>
            <% if (item.username===username) { %>
              <a href="/write?id=<%=item.id%>&page=<%=data.curPage%>">編集</a>
              <a href="/article/delete?id=<%=item.id%>&page=<%=data.curPage%>">削除</a>
            <%} else {%>
              <span class="grey">編集</span>
              <span class="grey">編集</span>
            <%}%>
          </span>
        </div>
      <% }) %>

这里使用if语句进行判断。username是从session中获取的当前登录用户的用户名,item.username分别是每篇文章的作者名。如果不匹配,则无法进行编辑和删除。

发布/部署

尚未公开,但我计划使用EC2进行公开。我会先记下以下文章,似乎会有所参考。

EC2是什么?从概述到使用方法的简要解释(包含实际操作)

[AWS] 在Amazon EC2上通过具有图片的步骤搭建Node.js和Express环境的教程:在Amazon EC2实例上设置Node.js
在AWS EC2上运行Node.js指南

在Amazon Linux上安装MongoDB Community Edition


我在途中停下来了。指令备忘录↓↓

$ ssh -i textapp-key.pem ec2-user@18.183.176.255

$ ssh -i textapp-key.pem ec2-user@18.183.176.255
$ sudo yum update
$ sudo yum install git gcc-c++ make openssl-devel
$ nvm install v16.14.0
$ nvm alias default v16.14.0
$ npm install express-generator -g

npm WARN deprecated mkdirp@0.5.1: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)

$ npm update -g mkdirp
$ npm install -g npm@8.5.3

$ git clone https://github.com/akikisai/Article-management-app.git
$ ls -a
$ cd Article-management-app/
$ npm install


$ grep ^NAME /etc/*release
/etc/os-release:NAME="Amazon Linux"

$ cd /etc/yum.repos.d
$ sudo touch mongo-org-5.0.repo
$ sudo su
# vi mongo-org-5.0.repo


[mongodb-org-5.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/5.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-5.0.asc

:wq!

# sudo yum install -y mongodb-org

exclude=mongodb-org,mongodb-org-database,mongodb-org-server,mongodb-org-shell,mongodb-org-mongos,mongodb-org-tools

# ps --no-headers -o comm 1
systemd

# sudo systemctl start mongod

# sudo systemctl status mongod
 Active: active (running) since Sat 2022-03-05 12:30:03 UTC; 29s ago

$ mongosh
>use textapp

>db.createCollection('users');
>db.createCollection('articles');


$ cd Article-management-app/
node ./bin/www

我失败了,我想再试一试其他的方法。


问题点

这次我只是试着创建了一些功能,但还没有写完善的错误处理(如用户名验证)和支持Markdown的功能,虽然还有很多新功能可以添加,但本次暂时先设定了截止时间。

广告
将在 10 秒后关闭
bannerAds