Forum and background built with node+mongodb

Keywords: Database Mongoose Session MongoDB

Forum and background built with node+mongodb

This is the first project background that I have done. If there are any inappropriateness and correction, please give me more advice. This project is only for reference! Thank you.
I put the source code at the bottom of the article. If you need it, you can go to my github and clone directly. I hope you can point a Star and give me some opinions and suggestions. Your support is my biggest motivation.

Main configuration

What is worth explaining is the middleware part:

  1. Express art template is a template engine used to render the data on the server to the page. Its features are: very fast, very quick response;
  2. Art template, on the other hand, can use the include extend block syntax to write the head and tail of the template page directly, and other sub pages can inherit it directly. Following chart
  3. Body parser can parse the form post request body
  4. Mongoose is a third-party package developed by the other party based on the official RE development. Of course, the official also has the official package of the corresponding middleware mongodb, but the official package is more cumbersome. It is time-saving and labor-saving to use mongoose directly, so mongoose is used here.

Functional interpretation

Router

Router is the framework of this project, so it is designed first. Basically, there will be home page, user's individual page, registration page, and login page. We also need to do the operations of registration, login, logout, and post.
get request

  • Home page (forum page):/
  • Registration page / register
  • Login page / login
  • Launch topic page / topics/new
  • User settings interface (change password): / settings/admin
  • Exit / logout
  • User settings interface / settings/profile
  • Article display interface / topic/show
  • Background management system interface display / background
  • background/view
  • background/user: background/user
  • background/user/delete
  • background/article
  • background/article/delete
  • background/comment
  • Delete background/comment/delete

post request

  • User registration submission form / register
  • User login submission form / login
  • User modification settings submission form / settings/profile
  • Save user's new password / settings/admin
  • Log off user / settings/delete
  • Post / topic/new
  • Submit comments / topic/show

Middleware introduction

var express = require('express')
var path = require('path')
var bodyParser = require('body-parser')
var session = require('express-session')
var router = require('./router')

var app = express();
//Open public and node modules
app.use('/public/', express.static(path.join(__dirname, './public/')))
app.use('/node_modules/',express.static(path.join(__dirname, './node_modules/')))

//express and art template
app.engine('html',require('express-art-template'))

// Configure the POST request body plug-in of the parsing form (Note: it must be before app.use(router))
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended:false }))
// parse application/json
app.use(bodyParser.json())

app.use(session({
    // Configure the encryption string, which will be combined with this string to encrypt based on the original encryption
    // The purpose is to increase security and prevent malicious forgery of clients
    secret: 'itcast',
    resave: false,
    saveUninitialized: false // Whether you use Session or not, I will assign you a key directly by default.
  }))


//Mount the route to the app 
app.use(router)


app.listen(3000,function(){
    console.log('has been running 3000')
})

Sign up / login

Here we focus on how to get the user information and change the information display on the forum homepage after the user logs in.

First of all, let's take a look at the first page of the forum.

Look at the upper right corner carefully. What we need to do is to show the user's login status, i.e. the user's status name, when the user logs in. We need to use session and art template here. First, the login button of the user's login interface initiates the request, and then the server receives the request and then initiates the request to the database to see if it is OK. If there is a user, the data will be returned, and then the session will be used to record the account password of the current user (but it is not safe, novice will play ~). The code is as follows:

 User.findOne({
        username: body.username,
        passwd: body.passwd
    }, function (err, user) {
        if (err) {
            return res.status(500).json({
                err_code: 500,
                message: err.message
            })
        }

        // If the mailbox and password match, user is the queried user object, otherwise it is null
        if (!user) {
            console.log(body.passwd)
            return res.status(200).json({
                err_code: 1,
                message: 'username or passwd  is invalid.'
            })
        }

        //The user exists, the login is successful, the login status is recorded, and the login status is recorded through the session.
        req.session.user = user

        res.status(200).json({
            err_code: 0,
            message: 'ok '
        })

After returning the data, use the art template template engine to judge the data. If there is user data, display another html element. The code is as follows

        {{ if user }}
        <a class="btn btn-default navbar-btn" href="/topics/new">Launch</a>
        <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"><img width="20" height="20" src="../public/img/avatar-max-img.png" alt=""> <span class="caret"></span></a>
          <ul class="dropdown-menu">
            <li class="dropdown-current-user">
              Current login user: {{ user.nickname }}
            </li>
            <li role="separator" class="divider"></li>
            <li><a href="/">homepage</a></li>
            <li><a href="/settings/profile">Set up</a></li>
            <li><a href="/logout">Sign out</a></li>
          </ul>
        </li>
        {{ else }}
        <a class="btn btn-primary navbar-btn" href="/login">Sign in</a>
        <a class="btn btn-success navbar-btn" href="/register">register</a>
        {{ /if }}

Different articles and comments

Set up a comment database, and then when commenting, assign the title of which article to the theme field of the database, and then match whether the field is the same as the theme of the article. If it is the same, it will be displayed, otherwise it will not be displayed. (here, I set up two databases for data storage, namely, article database and comment database)

The design of article database

var mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/hsuser', {useNewUrlParser: true});
var Schema = mongoose.Schema

var articleSchema = new Schema({
    theme:{
        type:String,
        required:true
    },
    username:{
        type:String
    },
    models:{
        type:String
    },
    //Time of publication
    atime:{
        type:Date
    },
    //content
    content:{
        type:String,
        required:true
    }
})
module.exports = mongoose.model('Article',articleSchema)

Design of comment database

var mongoose = require('mongoose')
mongoose.connect('mongodb://localhost:27017/hsuser', {useNewUrlParser: true});
var Schema = mongoose.Schema

var commentSchema = new Schema({
    theme:{
        type:String
    },
    nickname:{
        type:String
    },
    content:{
        type:String
    },
    time:{
        type:Date
    },
    good:{
        type:Number
    }
})

//export
module.exports = mongoose.model('Comment',commentSchema)

Using a nesting, we first find the corresponding article, and then we check the corresponding comments under the corresponding article.

//Article display
router.get('/topic/show', function (req, res) {
    //You need to make a judgment first. When the user is not logged in, prompt the user and return to the home page.
    if(req.session.user == null){
        return res.status(500).send('Please log in and check')
    }


    //console.log(req.body.id)
    //console.log(req.query.id)
    //console.log(req.session.user.nickname)
    Article.findById(req.query.id, function (err, article) {
        if (err) {
            console.log('fail')
            return res.status(500).send('Server error.')
        }
        //Nest it, read the data of comments, and put it in.
        //In order to search conditionally, find must conform to the syntax and add {theme:article.theme}.
        Comment.find({theme:article.theme},function(err,comment){
            if(err){
                console.log('fail')
                return res.status(500).send('Server error.')
            }
                res.render('./topic/show.html',{
                    user:req.session.user,
                    article:article,
                    comment:comment
                })
        })
    })
})

Problems encountered during

  1. The database that the user registers and logs in uses the same database, but the Forum opens another data on the user information. How to connect the database with the main foreign key in the middle? Because the database I use is mongodb and nosql, I am not familiar with the main foreign key, so it is stuck here.
    Solution: after the discussion with the teacher, the teacher said that there was a problem in my database design. I should design them into the same database rather than separate them. Generally, I do projects outside. The user's information is a database, instead of designing two databases like me and connecting them again. Moreover, even if two databases are used, there will be hundreds of millions of "_id" data in mongodb database even if it is not set. This ID is unique. As long as the ID is used well, it can be the information connection of corresponding database data through this ID.

  2. Login interface and background interaction ajax did not respond! Data can't be synchronized?
    Solution: it was the js file in the interface that elder martial sister gave us. When the user clicks the submit button, elder martial sister will trigger the condition of elder martial sister and return false, so I can't get to my ajax in any way, so the ajax I wrote is invalid. The final solution is to temporarily log off the js code of elder martial sister, and first get the front-end and background database to interact. First.

  3. When the login is successful, how to make the page remember the user's login and jump to the forum interface
    Solution: Here I use a middleware "express session" to save the user's login information on the browser's session. When I jump to the homepage, I can judge whether there is user information on the session. If there is any information, it means that the login is successful, and it shows that the login status of the successful user is above the forum.

  4. Do not know how to achieve, in the forum click on different articles, corresponding display different comments.
    Solution: set up a comment database, and when commenting, assign the title of the article to the theme field of the database, and then match whether the field is the same as the theme of the article. If it is the same, it will be displayed, otherwise it will not be displayed. (here, I set up two databases for data storage, namely, article database and comment database).

  5. Then question 4, about the implementation, here is the key
    Solution: there is no doubt that clicking the article on the home page will jump to the specific article. Here, we use the method of finById of mongoose middleware, and the ID is put on the url through art template. PS: when I query the ID on the url, I use it on the router I set (req.query.id); it is worth noting that there are three ways to get parameters on the node (req.query, req.body, req.params), so I won't go into details here. Three ways to get parameters ; then, it's the key to make use of a nesting. First, I found the corresponding article, and then I checked the corresponding comments under the corresponding article. This comment is to make use of find(theme:article.theme,function() {}) in mongoose, mainly the query conditions. Because I'm not familiar with the api of mongoose, I've been stuck here for a long time.

After all the above problems have been solved, a forum and user information will be completed. Then, the rest of the background information will be displayed and written. This step is also relatively simple. Using Tencent's art template engine, rendering the background mongodb database to the corresponding background interface can be completed.

summary

The reason why I only write the above two steps is that in the process of this exercise, the above two steps are the ones that are slightly hindered. Of course, there are other problems sometimes. But relatively speaking, I think it is more difficult to do the above two steps in this forum and background, but in fact, they are more basic. The most important thing is to see whether I can read the documents and use the API. This is very important! The rest is relatively simple, that is, using art template rendering and mongoose for CRUD; other details are on my github. red tourism , hope to give a star, your comments and suggestions are my biggest motivation ~ thank you!

Posted by curb on Sun, 27 Oct 2019 05:23:53 -0700