node.js+前端简单的问答系统

676 阅读3分钟

这是一个问答系统,可实现的功能主要有注册、登录、发布问题、解答问题、更换头像。其目的主要是为了巩固新学习的node.js知识。每一个新知识都有一个庞大的完整体系不求完全贯通,但一定要把常用、重要的知识运用熟练。
主页面预览

image.png 1.注册登录
进入问答系统可直接进入首页面 可进行浏览,使用提问功能需要先注册登录 注册.jpg 前端主要代码

            <input type="text" id="account" placeholder="输入账号 账号不能少于4位"><br>
            <label for="password">密码:</label><br>
            <input type="text" id="password" placeholder="输入密码 密码不能少于4位"><br>
            <label for="againpasword">再输密码:</label><br>
            <input type="text" id="againpasword" placeholder="输入相同密码"><br>
            <input type="submit" value="注册" onclick="registered()" class="zhuce">

前端主要js代码

                    var account = document.getElementById('account').value
                    var password = document.getElementById('password').value
                    var againpasword = document.getElementById('againpasword').value
                     var xhr = new XMLHttpRequest()
                    xhr.open('post', '/registered')
                    xhr.setRequestHeader('Content-Type',
                        'application/x-www-form-urlencoded')
                    xhr.send(`account=${account}&password=${password}`)
                    xhr.onreadystatechange = function () {
                        if (xhr.readyState == 4) {
                            if (xhr.responseText == '注册成功') {
                                location.href = './login.html'
                            } else {
                                alert(xhr.responseText)
                            }
                        }
                    }
                }

使用xhr请求的post方法进行数据请求。
后端写入'/registered'接口。同步创建'alluser.txt'用来储存注册的用户。

//表判断
fs.access('alluser.txt', (noExists) => {
    if (noExists) {
        fs.writeFileSync('alluser.txt', '[]')
    } else {
        fs.readFile('alluser.txt', 'utf-8', (err, data) => {
            alluser = JSON.parse(data)
        })
    }
})
    console.log(req.body);
    for (var index = 0; index < alluser.length; index++) {
        var aluser = alluser[index]
        if (aluser.account == req.body.account) {
            console.log('账号重复');
            res.send('账号已存在')
            return
        }
    }
    console.log('账号不重复');
    //默认头像
    req.body.header = './header/default.jpg'
    alluser.push(req.body)
    fs.writeFile('alluser.txt', JSON.stringify(alluser), (err) => {
        res.send('注册成功')
    })
})

用户注册后location.href="./login.html"跳转到登录界面

image.png 前端html代码和js代码
这里同样使用xhr请求的post方法进行数据请求。

            <label for="password">密码:</label><input type="text" id="password"><br>
            <input type="submit" value="登录" onclick="clogin()" class="denglu">
                    var account = document.getElementById('account').value
                    var password = document.getElementById('password').value
                     var xhr = new XMLHttpRequest()
                    xhr.open('post', '/login')
                    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
                    xhr.send(`account=${account}&password=${password}`)
                    xhr.onreadystatechange = function () {
                        if (xhr.readyState == 4) {
                            console.log(xhr.responseText);
                            if (xhr.responseText == '登录成功') {
                                location.href = "./index.html"
                            }if(xhr.responseText=='账号未注册'){
                                alert('账号未注册')
                            }
                        }

                    }
                }

后端写入'/login'接口,注册后的用户信息已经存储在'alluser.txt'内,登录的逻辑是对'alluser'进行遍历把带索引的alluser赋值给aluservar aluser = alluser[index],把前端发送过来的账号密码与后端遍历出来的已经注册的账号密码进行比对。

    for (var index = 0; index < alluser.length; index++) {
        var aluser = alluser[index]
        if (aluser.account == req.body.account) {
            if (aluser.password == req.body.password) {
                res.cookie('uname', req.body.account)
                res.send('登录成功')
            }
            else {
                res.send('密码错误')
            }
            return
        }
    }
    res.send('账号未注册')
})

登录成功

QQ截图20210618111048.jpg

我要回答功能
点击我要回答功能如果没登录会跳转到登录页面,选择登录之后才能回答问题
点击回答弹出输入答案模态框

            var content = $('textarea').val()
            console.log(content);
            if (content.length == 0) {
                alert('不提出问题就提交有点不讲究吧🤠🤠🤠')
                return
            }
            //此处写一个post请求 向后台发送 内容 索引 问题的人
            var xhr = new XMLHttpRequest()
            xhr.open('post', '/submitAnswer')
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
            xhr.send(`content=${content}&index=${$.cookie('index')}&answerMan=${$.cookie('uname')}`)
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4) {
                    console.log(xhr.responseText);
                    //回答之后隐藏模态框
                    $('#myModal').modal('hide')
                    //清空框里面的内容
                    $('textarea').val('')
                    location.href = ('./index.html')
                }
            }
        }

image.png 回答框内不输入内容无法提交输入内容后点击提交

web.post('/submitAnswer', (req, res) => {
    console.log(req.body);
    var findUser = alluser.filter(function (el) {
        return el.account = req.body.answerMan
    })
    var answer = {
        //回答的内容
        content: req.body.content,
        //回答的人的头像
        header: findUser[0].header,
        //回答的人
        answerMan: req.body.answerMan,
        //回答的时间
        time: getTime(),

    }
    //这里是把回答的东西放入到指定问题的答案的第一个位置
    getallquestion[req.body.index].answerList.unshift(answer)
    //然后重新写入
    fs.writeFile('getallquestion.txt', JSON.stringify(getallquestion), (err) => {
        res.send('回答成功')
    })

})

image.png 登录成功后可执行退出登录个更换头像操作

image.png

点击上传头像通过form表单post方法'/upphoto'接口提交到后台

 <form action="/upphoto" method="POST" enctype="multipart/form-data">
                👉<label for="pho">🐷</label>👈<br>
                <input type="file" name="photo" id="pho" accept="image/*" required class="hide">
                <input type="submit" name="" id="" class="btn btn-primary" value="上传">
            </form>
            

在后台配置信息以及接收上传头像

//之所以写在存放注册用户密码后面是使用alluser
//上传头像 配置上传信息 路径和名字
var headerName = ''
var diskStorage = multer.diskStorage({
    destination: function (req, file, callback) {
        callback(null, './public')
    },
    filename(req, file, callback) {
        var splitArray = file.originalname.split('.')
        var type = splitArray[splitArray.length - 1]
        headerName = './header/' + req.cookies.uname + '.' + type
        var index = alluser.findIndex(function (el) {
            return el.account == req.cookies.uname
        })
        alluser[index].header = headerName
        fs.writeFile('alluser.txt', JSON.stringify(alluser), (err) => {

        })
        callback(null, headerName)
    }
})

//再上传头像
var headerConfig = multer({ storage: diskStorage })
//此处是上传头像的接口
web.post('/upphoto', headerConfig.single('photo'), (req, res) => {
    console.log(req.body);
    getallquestion.forEach(function (el) {
        //提问的人和上传头像的人是同一个人 上传头像
        if (el.askquestion == req.cookies.uname) {
            el.header = headerName
        } if (el.answerList) {
            el.answerList.forEach(ans => {
                if (ans.answerMan == req.cookies.uname) {
                    ans.header = headerName
                }
            })
        }
    })
    fs.writeFile('getallquestion.txt', JSON.stringify(getallquestion), (err) => {
        res.send("<script>location.href='/'</script>")
    })

})

image.png 点击退出登录 设置退出登录函数把登录的用户名cookie值清空并刷新页面

 function recookie() {
            $.cookie('uname', '')
            location.href = './index.html'
        }

image.png