1. Create folders

2. Introduce JS modules

3. Add bootstrap. CSS, bootstrap.js, jquery. js, and jquery-cookie. js to the HTML file

4. Register user page

5. Log in to the user page

6. Questions page

7. I’ll answer

8. Upload your profile picture

  • Create a q&A system folder, create a public folder in this folder to store the front-end code, initialize NPM, create an index.js file,

Fixed module introduction and fixed code for POST requests.

  • Create an index. HTML file in the public folder and adjust the layout of the page.
<nav class="navbar navbar-inverse navbar-orange" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#example-navbar-collapse"> <span Class ="sr-only"> </span> <! - the fonts icon - > < span class = "icon - bar" > < / span > < span class = "icon - bar" > < / span > < span class = "icon - bar" > < / span > < / button > < a Class ="navbar-brand" href="#"> <div class="collapse navbar-collapse" id="example-navbar-collapse"> <ul Class ="nav navbar-nav"> <li ><a href="#"> <span class="glyphicon glyphicon-search"></span> question </a></li> <li Id ="regist"><a href="login.html"> <span class="glyphicon glyphicon-plus"></span> </a></li> <li id="dropdown" Class ="dropdown hide"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" Class = "dropdown can - menu" > < li > < a href = "#" > upload picture < / a > < / li > < li > < a onclick = 'logout ()' > log out < / a > < / li > < / ul > < / li > < / ul > < / div > </div> </nav>Copy the code

Check whether you have logged in in the script. If you have logged in, the figure below shows the account number and hides the login button; if there is no account, the figure above shows the login button and hides the account name.

Var cookieName = $. Cookie ('loginName') if(cookieName){$('#regist').addClass('hide'); $('#dropdown').removeClass('hide').addClass('show') } else{ $('#regist').addClass('show').removeClass('hide') $('#dropdown').removeClass('show').addClass('hide') }Copy the code

Set a click event for the logout button to return to the home page

function logout(){
            $.removeCookie('loginName')
            window.location.href= '/'
        }
Copy the code
  • Set up the registration page, page basic navigation copy the home page, make changes. Write the input account password and reset the password input box in the page
<div class="container"> <div class=""> <label for=""> account :</label> <input type="text" id="user" class="form-control"> < / div > < br > < div class = "" > < label for =" "> password: < / label > < input type =" text "id =" password "class =" the form - control "> < / div > < br > <div class=""> <label for=""> repeat password :</label> <input type="text" id="again" class="form-control"> </div> <br><br> <button Onclick ="clickRegist()" class="form-control btn-success">Copy the code

To set a button click event, click on the registration after the access to enter the account password and reset the password, the password may not be less than six characters, and shall be the same password and reset the password, var an XHR request, use a post request sent to the backend, at the same time receive the data returned to the end, the back-end returns the “registration”, The login page is displayed

function clickRegist(){ var user = $("#user").val() var psw = $('#password').val() var again = $("#again").val() If (user.length < 6){alert(' password must be at least 6 digits ') return} if(PSW. Length < 6){alert(' password must at least 6 digits ') return} if(PSW! Var XHR = new XMLHttpRequest() xhr.open('post', '/regist') xhr.setRequestHeader("Content-Type" , 'application/x-www-form-urlencoded') xhr.send(`account=${user}&password=${psw}`) xhr.onreadystatechange = function(){ If (xhr.readyState == 4){if(xhr.responseText == 'registered '){location.href = 'login.html'} else{alert(xhr.responsetext)} }}}Copy the code
  • TXT file, enter the contents of the array allUserArray, if there is, read the contents of allUser. TXT, assign to the array allUserArray

  • Json.stringify () converts a JavaScript object to a JSON string, while json.parse () converts a JSON string to an object. The difference between

var allUserArray = []
fs.access('allUser.txt', function(noExists){
    if(noExists){
        fs.writeFileSync('allUser.txt' , JSON.stringify(allUserArray))
    }
    else{
        fs.readFile("allUser.txt", 'utf-8' , function(err , data){
            allUserArray = JSON.parse(data)
        })
    }
})
Copy the code
  • Set the back-end registration code. According to the POST request set by the front end, / REGist interface receives the content sent by the front end and makes a circular comparison between the content sent by the front end and the data in allUserArray. If the account is repeated, it is registered, and if the account is not repeated, the registration is successful. At the same time, push the passed account password into the first allUserArray array, and then write the allUserArray into the text alluser.txt, and return a “registration success” message to the front end.
web.post('/regist',function(req ,res){ console.log(req.body); for(var index = 0 ; index < allUserArray.length ; Index ++){var user = allUserArray[index] if(user.account == req.body.account){res.send(' this account is registered ') return}} // Header = './header/defualt.png' allUserArray.push(req.body) fs.writefile (' alluser.txt ', Json.stringify (allUserArray), function(err){res.send(' registered successfully ')})})Copy the code
  • Set the login page. The basic navigation of the page replicates the home page, and the account and password input box can be modified according to the registration page.

Set a click event for the login button. After the login button is clicked, the entered account password is obtained, and the account password cannot be less than six characters. Var An XHR request is sent to the back end using post request, and the data returned by the back end is received. The code adjusts according to the registration code.

  • Set the back-end login code. According to the POST request set by the front-end, the /login interface receives the content sent by the front-end and makes a cyclic comparison between the content sent by the front-end and the data in allUSerArray. If the account already exists, it will judge whether the password is the same and the password is the same, and return the account as cookieName to the front-end. At the same time, the login succeeded message is displayed. If the account and password are different, “Login failed, password is incorrect” is displayed. If the account is different, “Login failed, the account is not registered” is returned.
web.post('/login',function(req ,res){ console.log(req.body); for(var index = 0 ; index < allUserArray.length ; index ++){ var user = allUserArray[index] if(user.account == req.body.account){ if(user.password == req.body.password){ res.cookie("loginName" , Req.body.account) res.send(" login failed, password error ")} else{res.send(" login failed, password error ")} return}} res.send(" login failed, password error ")})Copy the code
  • Create a new allQuestionArray array at the back end and check whether there is question. TXT. If there is no, create a new text and write allQuestionArray into question. Assign the new data to allQuestionArray
var allQuestionArray = []
fs.access('question.txt',function(noExists){
    if(noExists){
        fs.writeFileSync('question.txt' , JSON.stringify(allQuestionArray))
    }
    else{
        fs.readFile('question.txt' , 'utf-8' , function(err , data){
            allQuestionArray = JSON.parse(data)
        })
    }
})
Copy the code
  • Set a click event for the question button on the home page. If you have logged in, it will jump to the question page; if you have not logged in, it will jump to the login interface.
 function toQuestion() {
            if (cookieName) {
                location.href = 'question.html'
            }
            else {
                window.location.href = 'login.html'
            }
        }
Copy the code
  • Query page Basic navigation Copy the previous login interface, modify the input box to textarea box, and simply modify the rest. Add a click event to submit the question button to obtain the input content, which cannot be empty. Send the content and user name to the back end with individual request. At the same time, obtain the data returned by the back end, “Ask succeeded”, and the page jumps back to the home page.
Function clickToQuestion(){var question = $("textarea").val() if(question.length == 0){alert(' question cannot be empty ') return} var xhr = new XMLHttpRequest() xhr.open('post' , '/question') xhr.setRequestHeader("Content-Type" , 'application/x-www-form-urlencoded') xhr.send(`question=${question}&user=${$.cookie("loginName")}`) Xhr.onreadystatechange = function(){if(xhr.readyState == 4){if(xhr.responseText == 'success '){location.href = function(){if(xhr.responseText ==' success '){location './index.html' } else{ alert(xhr.responseText) } } } }Copy the code
  • Set up the question request at the back end, find the same person as the current question from all the registered people, and summarize all the information into a variable question. GetTime () function is to get the time of the current moment, and write relevant codes in index.js
Function getTime(){var time = new Date() time = time.tolocaleString (); var time = new Date() time = time.tolocaleString (); '-') time = time.replace(' morning ', ") time = time.replace(' afternoon ', ") return timeCopy the code
web.post('/question',function(req ,res){ console.log(req.body); Var register = allUserArray.filter(function(el){return el.account == req.body.user}) var question = {// Asker: the req. Body. The user, the question content the content: / / the req. Body. Question, / / questions from time to time: getTime (), / / ask the pictures the header: Register [0].header, // answerList:[]} allQuestionarray.unshift (question) fs.writefile ('question.txt', Json.stringify (allQuestionArray), function(err){res.send(' question successful ')})})Copy the code

Place the latest question in the first place in the allQuestionArray array, and write the contents of the array to the question.txt text to return a “successful question” to the front end.

  • When the question is displayed on the home page, a function needs to be written into the script of the home page, which uses get request and interface bit getQuestion to pass empty information to the back end. Meanwhile, it accepts all the arrays of questions returned by the back end and assigns the array values to a newly defined variable questionList. Loop through questionList to write each question to HTML
function getAllQuestion() { var xhr = new XMLHttpRequest() xhr.open('get', '/getQuestion') xhr.send() xhr.onreadystatechange = function () { if (xhr.readyState == 4) { var questionList = JSON.parse(xhr.responseText) // console.log(questionList); var html = '' for (var index = 0; index < questionList.length; index++) { var question = questionList[index] html += ` <div class="panel panel-danger getMargin"> <div class="panel-heading"> <h3 class="panel-title"> ${question.asker} <img class="header" src='${question.header}'> ${question.time} </h3> </div> <div class="panel-body questionPanel"> <div class="questionContent"> ${question.content} </div> <button onclick="clickToAnswer(${index})" class=" BTN btn-success answertn" class='answerPanel'></div> </div> </div> ` } $('#list').html(html) } } } getAllQuestion()Copy the code

The backend receives a request for a question from the front end and returns an array containing all the questions to the front end.

web.get('/getQuestion',function(req ,res){
    res.send(allQuestionArray)
})
Copy the code
  • I will answer: find the template of the modal box in the Bootstrap library and put it in HTML. Add a click event to the “I will answer” button on the home page to determine whether it is logged in. The modal box will pop up once logged in, and keep the index of the question. If you are not logged in, the login page is displayed.
Function clickToAnswer(index) {if (cookieName) {// Pop up the modal box // Alert () $('#myModal'). Modal ('show') // Reserve the index of the question $.cookie('index', index) } else { location.href = 'login.html' } }Copy the code

Popup modal dialog to answer button to add a click event, to get to the content of the message box, to determine whether a message box is empty, by the content of the post request to send the back-end answer, answer, answer is which one index (the problem), if the content of the modal dialog is not null, hidden modal box, clear the data content.

Function sendAnswer() {var content = $('textarea').val() if (content.length == 0) {alert(' content cannot be empty ') return} var XHR = new XMLHttpRequest() xhr.open('post', '/sendAnswer') xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') xhr.send(`content=${content}&index=${$.cookie('index')}&answerMan=${cookieName}`) xhr.onreadystatechange = function () { if (xhr.readyState == 4) { // console.log(xhr.responseText); / / hide the modal dialog $(' # myModal). Modal (' hide ') / / clear input $(' textarea). Val (" ") / / for the latest content on the location. The href = '/'}}}Copy the code
  • The answer request is received at the back end, and the same person as the current answer is found from all the registered people. All the information is summarized in a variable answer. The getTime() function is to get the time of the current moment, and relevant codes are written in index.js

Put the latest answer into the array allQuestionArray to specify the first position of all the answers to the question, and write the contents of the array into the text question.txt to return a “successful answer” to the front end.

web.post('/sendAnswer',function(req ,res){ console.log(req.body); Var findUser = allUserArray.filter(function(el){return el.account == req.body.answerman}) var answer = {// Answer person AnswerMan: the req. Body. AnswerMan, / / answer content content: the req. Body. The content, / / time time: getTime (), // findUser[0].header} // Place the latest answer in the first place of all the answers in the specified question allQuestionArray[req.body.index].answerList.unshift(answer) fs.writeFile('question.txt' , Json.stringify (allQuestionArray),function(){res.send(" answer successful ")})})Copy the code

To display the answer in the front page, append answerHtml to the page by adding the answer to the getAllQuestion() function you set up earlier and the answer to the question’s for loop.

var answerHtml = '' for (var a = 0; a < question.answerList.length; a++) { var answer = question.answerList[a] console.log(answer); answerHtml += ` <div class="panel panel-success dropMargin " style="text-align:right"> <div class="panel-heading"> <h3 class="panel-title"> ${answer.answerMan} <img class="header" src='${answer.header}'> ${answer.time} </h3> </div> <div class="panel-body questionPanel"> <div class="questionContent"> ${answer.content} </div> </div> </div> ` } // HTML += answerHtml $('#list').html(HTML)}}} getAllQuestion()Copy the code
  • Upload avatar: The front end adds a click event to the upload avatar button
function getHeader(){
            var xhr = new XMLHttpRequest()
            xhr.open('get' , '/getHeader')
            xhr.send()
            xhr.onreadystatechange = function(){
                if(xhr.readyState == 4){
                    $('#header').attr('src' , xhr.responseText)
                }
            }
        }
Copy the code

The back end performs some operations on the profile picture information, such as image segmentation, image format acquisition, and the latest image address stitching

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 HeaderName = './header/' + req.cookies. LoginName + '.' + type console.log(headerName); Var index = allUserArray.findIndex(function(el){return el.account ==) var index = allUserArray.findIndex(function(el){return el.account == Req.cookies. LoginName}) // Set the user profile picture to the latest profile picture allUserArray[index]. Header = headerName fs.writefile (" alluser.txt ", JSON.stringify(allUserArray), function(err){ }) callback(null , headerName) } })Copy the code

Change the profile pictures of all the questioners and answerers who are the same as the person who uploaded the profile picture to the profile picture you just uploaded.

var headerConfig = multer({storage:diskStorage}) web.post('/upload' , Single ("photo"),function(req,res){allQuestionarray. forEach(function(el){// If (el.asker) == req.cookies. LoginName){el.header = headerName} if(el.answerList){el.answerlist. ForEach (ans => {// The answer is the same as the person who uploaded the profile picture if(ans.answerMan == req.cookies.loginName){ ans.header= headerName } }); } }) fs.writeFile('question.txt' , JSON.stringify(allQuestionArray) ,function(){ res.send("<script>location.href='/'</script>") }) })Copy the code

Results: