Help us understand the problem. What is going on with this article?

expressで掲示板をつくる

More than 1 year has passed since last update.

expressを使い始めた初心者です.指摘やアドバイス等あればコメントをしてください.

環境

node v6.11.2
express 4.15.2
テンプレートエンジンにejsを使用
データベースはNeDB

準備

まずは必要なものををインストール

npm install -g express-generator
express --view=ejs bbs
cd bbs
npm install
npm install --save express-session
npm install --save csurf
npm install --save nedb

コード

express-generatorでつくられたファイルの構造は以下の通り

  • bin
    • www
  • node_modules
  • public
    • images
    • javascripts
    • stylesheets
  • routes
    • users.js
    • index.js
  • views
    • error.ejs
    • index.ejs
  • app.js

これらのファイルを必要に応じて変更,書き換えしていく

app.js(追加したものだけ)
const expressSession = require('express-session');
const csrf = require('csurf');

app.use(expressSession({secret: 'secret_key'}));
app.use(csrf({cookie: true}))
app.use((req, res, next) => {
  res.locals.csrftoken = req.csrfToken();
  next()
})

app.jsに書き加えたのはcsrf対策に必要なモジュール

routes/index.js
const express = require('express')
const router = express.Router()
const nedb = require('nedb')
db = new nedb({
  filename: 'bbs.db',
  autoload: true
})
/* GET home page. */
router.get('/', function(req, res, next) {
  db.find({}).sort({time: 1}).exec((err, data) => {
    if (err) {
      res.send('dberror')
      return
    }
    let obj = {}
    for (let i=0; i < data.length ; i++) {//data配列をobjectに
      obj[i]=data[i]
    }
    res.render('index', {
      obj: obj,
      len: data.length
    })
  })
})

router.post('/post', (req, res) => {
  const name = req.param("name")
  const body = req.param("body")
  if ( !name || !body ) {
    res.send('名前もしくは本文を入力してください')
    return
  }
  db.insert({
    name: name,
    body: body,
    time: (new Date()).getTime()
  }, (err, doc) => {
    if (err) {
      res.send('dberror');
      return
    }
  })
  res.redirect("/")
})

module.exports = router;

'/'でアクセスしてきたら掲示板(index.ejs)を表示する.NeDBから読み込んだデータは時間順にソートしてobjに格納し,index.ejsには名前と本文の入っているオブジェクトobjと,NeDBに登録されたデータの個数を渡す.
'/post'でpostされたデータをNeDBに登録する

views/index.ejs
<!DOCTYPE html>
<html>
  <head>
    <title>BBS</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1>BBSへようこそ</h1>
    <form action="/post" method="post">
      <input type="text" name="name" value="">
      <input type="text" name="body" value="">
      <input type="hidden" name="_csrf" value="<%= csrftoken %>"><!--csrf対策-->
      <input type="submit" name="" value="送信">
    </form>
    <ul>
      <% for(let i=0;i < len;i++){ %>
        <li><%= obj[i].name + ' : ' + obj[i].body %></li>
      <% } %>
    </ul>
  </body>
</html>

XSS対策のエスケープはejsの<%= %>でできるらしい

実行

/bbs
npm start

上記コマンドで実行できる.実行されているのは/bbs/bin/wwwで,wwwは拡張子がないがjavascriptで書かれたファイルであるので,

/bbs/bin
node www

でも実行できる.

感想

掲示板はPHPでフレームワークを使わずに作ったことがあったが,そのときよりも簡単に作れたと思う.ただ,フレームワーク初心者なのでどこのファイルに何を記述すればいいのか迷った.
次はチャットみたいなWebSocketを利用するものを作りたい.

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away