node+koa2+mysql+bootstrap搭建论坛前后端

这次给大家带来node+koa2+mysql+bootstrap搭建论坛前后端,node+koa2+mysql+bootstrap搭建论坛前后端的注意事项有哪些,下面就是实战案例,一起来看一下。

相关mysql视频教程推荐:《mysql教程》

前言

在学习了koa2和express并写了一些demo后,打算自己写一个项目练练手,由于是在校生,没什么好的项目做,即以开发一个前端论坛为目标,功能需求参照一下一些社区拟定,主要有:

登录注册

个人信息维护、头像等基本信息

发表文章,富文本编辑器采用wangEditor插件,编辑、删除文章,文章分类等

文章评论、文章收藏、点赞等

支持文章分页、评论分页加载

关注取关用户

资源(文件)上传分享、下载、查看

学习资源推荐…..

作者个人日记

but。。。。由于种种原因,目前仅实现了部分功能,资源分享还没写

项目运行效果:http://120.77.211.212https://www.php.cn/home

项目技术栈应用:node-koa2-ejs-bootstrap3—jquery, github地址:https://github.com/Jay214/myblog-koa2,如果觉得对你有帮助或者还看得下去,欢迎star~~鼓励鼓励我这前端渣渣辉。

开发环境

node: v8.3.0

koa: ^2.4.1

mysql: 5.7.1

npm: 5.3.0及以上

如何运行项目

将项目clone至本地 git clone git@github.com:Jay214/myblog-koa2.git

安装模块中间件 npm install

安装mysql

mysql版本推荐使用5.7以下的,5.7的有个bug,图形化界面推荐使用navicat for MySQL

运行可以安装supervisor(npm install supervisor 项目运行工具,开启后即处于监听模式,修改文件后保存即可,无需再启动项目) node index 或npm supervisor index

localhost:8080https://www.php.cn/home 端口号可自行修改

若发现项目有存在什么bug或有比较好的建议欢迎多多提议,qq:2752402930。

准备工作

由于koa2是基于es6的promise和es7的await/async语法,所以如果对es6/es7不懂的话请先过一遍文档,后台搭建数据库是关键,所以请先安装好mysql,mysql建议安装5.7版本以下的,因为5.7.0版本有个bug,需要更改配置文件,具体若你们安装的时候便知道了。

安装node环境,使用node -v查看node版本,node需要较新版本能够支持es6的promise和es7的await/async语法,现在node版本都会自带npm的,所以不需要再去安装npm。

项目结构

node+koa2+mysql+bootstrap搭建论坛前后端

1.config存放默认文件(数据库连接配置)

2.lib存放数据库文件

3.middlewares存放判断登陆注册与否中间件

4.public存放静态文件,js,引用bootstrap框架等文件

5.routers存放路由文件

6.views存放模板文件

7.index是程序主文件,定义接口,数据库接口,引用模块等

8.package.json项目的配置文件,包括项目名,作者,依赖,模块等

项目用vscode开发的,用起来很舒服,还没尝试过的小伙伴赶紧去试一下吧。

项目初始化:cd myblog1 -> npm init 此时已经创建好了package.json文件了。

由于koa2是轻量级的框架,小巧精悍,所以我们为了促进我们的开发效率和方便性,我们需要安装一些koa2的模块中间件:

npm install i koa koa-bodyparser koa-mysql-session koa-router koa-session-minimal koa-static koa-views md5 moment mysql ejs koa-static-cache --save-dev

登录后复制

各模块用处

koa node框架

koa-bodyparser 表单解析中间件

koa-mysql-session、koa-session-minimal 处理数据库的中间件

koa-router 路由中间件

koa-static 静态资源加载中间件

ejs 模板引擎

md5 密码加密

moment 时间中间件

mysql 数据库

koa-views 模板呈现中间件

koa-static-cache 文件缓存

项目基本框架搭建

配置数据库连接

在config文件夹新建default.js :

const config = {  //启动端口 port: 8080, //数据库配置  database: {  DATABASE: 'nodesql',  USERNAME: 'root',  PASSWORD: '123456',  PORT: '3306', HOST: 'localhost'  }}module.exports = config;

登录后复制

然后在lib文件夹新建mysql.js:

var mysql = require('mysql');var config = require('../config/default.js')//建立数据库连接池var pool = mysql.createPool({ host: config.database.HOST, user: config.database.USERNAME, password: config.database.PASSWORD, database: config.database.DATABASE});let query = function(sql, values) { return new Promise((resolve, reject)=>{ pool.getConnection(function (err,connection) {  if(err){ reject(err);  }else{  connection.query(sql,values,(err,rows)=>{    if(err){    reject(err);   }else{   resolve(rows);    }    connection.release(); //为每一个请求都建立一个connection使用完后调用connection.release(); 直接释放资源。       //query用来操作数据库表  })  }   })  })}

登录后复制

这里建立了一个数据库连接池和封装了一个操作数据库表的函数,如果对于数据库连接有不懂的话请自行百度。

建立入口文件

在主目录新建index.js,即项目入口文件:

const koa = require("koa"); //node框架const path = require("path"); const bodyParser = require("koa-bodyparser"); //表单解析中间件const ejs = require("ejs"); //模板引擎const session = require("koa-session-minimal"); //处理数据库的中间件const MysqlStore = require("koa-mysql-session"); //处理数据库的中间件const router = require("koa-router"); //路由中间件const config = require('./config/default.js'); //引入默认文件const views = require("koa-views"); //模板呈现中间件const koaStatic = require("koa-static"); //静态资源加载中间件const staticCache = require('koa-static-cache')const app = new koa();//session存储配置,将session存储至数据库const sessionMysqlConfig = { user: config.database.USERNAME, password: config.database.PASSWORD, database: config.database.DATABASE, host: config.database.HOST,}//配置session中间件app.use(session({ key: 'USER_SID', store: new MysqlStore(sessionMysqlConfig)}))//配置静态资源加载中间件app.use(koaStatic( path.join(dirname , './public')))//配置服务端模板渲染引擎中间件app.use(views(path.join(dirname, './views'),{ extension: 'ejs'}))//使用表单解析中间件app.use(bodyParser({ "formLimit":"5mb", "jsonLimit":"5mb", "textLimit":"5mb"}));//使用新建的路由文件//登录app.use(require('./routers/signin.js').routes())//注册app.use(require('./routers/signup.js').routes())//退出登录app.use(require('./routershttps://www.php.cn/signout.js').routes())//首页app.use(require('./routershttps://www.php.cn/home.js').routes())//个人主页app.use(require('./routers/personal').routes())//文章页app.use(require('./routershttps://www.php.cn/articles').routes())//资源分享app.use(require('./routershttps://www.php.cn/share').routes())//个人日记app.use(require('./routers/selfNote').routes())//监听在8080端口app.listen(8080) console.log(`listening on port ${config.port}`)

登录后复制

上面代码都有注释,我就不一一说明了,由于资源分享和个人日记还没写,所以暂时统一share…替代。

接下来向mysql.js添加数据库操作语句,建表、增删改查。

var users = `create table if not exists users( id INT(200) NOT NULL AUTO_INCREMENT, name VARCHAR(100) NOT NULL, pass VARCHAR(40) NOT NULL, avator VARCHAR(100) DEFAULT 'default.jpg',  job VARCHAR(40), company VARCHAR(40), introdu VARCHAR(255), userhome VARCHAR(100), github VARCHAR(100), PRIMARY KEY (id));`var posts = `create table if not exists posts( id INT(200) NOT NULL AUTO_INCREMENT, name VARCHAR(100) NOT NULL, title VARCHAR(100) NOT NULL, content TEXT NOT NULL, uid INT(200) NOT NULL, moment VARCHAR(40) NOT NULL, comments VARCHAR(255) NOT NULL DEFAULT '0', pv VARCHAR(40) NOT NULL DEFAULT '0', likes INT(200) NOT NULL DEFAULT '0', type VARCHAR(20) NOT NULL, avator VARCHAR(100), collection INT(200) NOT NULL DEFAULT '0',  PRIMARY KEY (id) , FOREIGN KEY (uid) REFERENCES users(id) ON DELETE CASCADE);`var comment= `create table if not exists comment( id INT(200) NOT NULL AUTO_INCREMENT, name VARCHAR(100) NOT NULL, content TEXT NOT NULL, moment VARCHAR(40) NOT NULL, postid INT(200) NOT NULL, avator VARCHAR(100), PRIMARY KEY ( id ), FOREIGN KEY (postid) REFERENCES posts(id) ON DELETE CASCADE);`var likes = `create table if not exists likes( id INT(200) NOT NULL AUTO_INCREMENT, name VARCHAR(100) NOT NULL, postid INT(200) NOT NULL, PRIMARY KEY (id), FOREIGN KEY (postid) REFERENCES posts(id) ON DELETE CASCADE);` var collection = `create table if not exists collection( id INT(200) NOT NULL AUTO_INCREMENT, uid VARCHAR(100) NOT NULL, postid INT(200) NOT NULL, PRIMARY KEY (id), FOREIGN KEY (postid) REFERENCES posts(id)  ON DELETE CASCADE );` var follow = `create table if not exists follow(  id INT(200) NOT NULL AUTO_INCREMENT,  uid INT(200) NOT NULL,   fwid INT(200) NOT NULL DEFAULT '0',  PRIMARY KEY (id),  FOREIGN KEY (uid) REFERENCES users(id)  ON DELETE CASCADE ) `let createTable = function(sql){ return query(sql, []);}//建表createTable(users);createTable(posts);createTable(comment);createTable(likes);createTable(collection);createTable(follow);//createTable(follower);//注册用户let insertData = function(value){ let _sql = "insert into users(name,pass) values(?,?);" return query(_sql,value);}//更新头像let updateUserImg = function(value){ let _sql = "update users set avator=? where id=?" return query(_sql,value);}//更新用户信息let updateUser = function(value){ let _sql = "update users set name=?,job=?,company=?,introdu=?,userhome=?,github=? where id=?" return query(_sql,value);}//发表文章let insertPost = function(value){ let _sql = "insert into posts(name,title,content,uid,moment,type,avator) values(?,?,?,?,?,?,?);" return query(_sql,value);}//更新文章评论数let updatePostComment = function(value){ let _sql = "update posts set comments=? where id=?" return query(_sql,value);}.......

登录后复制

总共六张表:用户表、文章表、文章评论表、文章收藏表、文章点赞表、用户关注表。

这里引用了外键,但是现在的开发不推荐使用外键了,所以你们可以自行修改,这里在项目第一次启动时会出现数据库创建失败(由于外键原因),只要重新启动就ok了,如果对mysql还不了解的,这里附送大家一个传送门:mysql入门视频教程 密码:c2q7 。

前端页面开发

项目基本结构搭建好后,就可以进行前端页面的编写了。用node开发web时我们一般会配合模板引擎,这个项目我采用的是ejs,除了ejs之外较为常用的还有jade,但是jade相对ejs来说的话代码结构不够清晰。关于ejs语法,这里做个简单的介绍:

header.ejs

   Myblog    

登录后复制

nav.ejs

       var searchInput = document.getElementsByClassName('search')[0]; searchInput.onfocus = function () {  this.style.width = "300px"; } searchInput.onblur = function () {  this.style.width = "180px"; }  

登录后复制

login.ejs

用户注册

来吧骚年们!

已有账号? 登录

// $(document).ready(function () { var $close = $('.login-close'); var $sign = $('.sign'); $close.click(function () { $sign.css("display","none"); }) var $register = $('.register'), //login/loginup切换 $span = $('.form-tips span'), $signup = $('.signup'), $signTitle = $('.sign-title h1'), $signin = $('.signin'); $register.click(function () { if($span.html() == "已有账号?"){ $signin.css('display','block'); $signup.css('display','none'); $(this).html('注册'); $span.html("没有账号?"); $signTitle.html("欢迎登录"); }else{ $signin.css('display','none'); $signup.css('display','block'); $(this).html('登录'); $span.html("已有账号?"); $signTitle.html("欢迎注册"); } }) var $loginup = $('.loginup'); //点击登录/注册,阻止事件冒泡 $loginup.click(function () { $mask.fadeIn(100); $sign.slideDown(200); return false; }) var $close = $('.login-close'), $mask = $('.login-form-mask'), $sign = $('.sign'); $sign.click(function () { return false; }) $close.click(function (e) { // e.stopPropagation(); fadeOut(); }) $(document).click(function (e) { //点击任意位置取消登录框 //e.stopPropagation(); fadeOut(); }) function fadeOut(){ $mask.fadeOut(100); $sign.slideUp(200); } var loginUp = document.getElementsByClassName('login-up')[0], loginIn = document.getElementsByClassName('login-in')[0], signUp = document.getElementsByClassName('signup')[0], signIn = document.getElementsByClassName('signin')[0]; loginUp.onclick = function () { //注册 var data1 = 'username=' + signUp["username"].value + '&' + 'pass='+ signUp["pass"].value + '&' + 'repeatpass=' + signUp["repeatpass"].value; var reg = /^[u4E00-u9FA5]{2,5}$/; /* if(!reg.test(signUp["username"].value)){ signUp["username"].classList.add("tips"); signUp['username'].value() } */ ajax('post','/signup',data1,"application/x-www-form-urlencoded"); xhr.onreadystatechange = function () { if(xhr.readyState==4&&xhr.status>=200&&xhr.status{ window.location.reload(); },1000) // document.getElementsByClassName('login')[0].outerHTML = "
  • "+signUp["username"].value+ "(=^ ^=)" +"
  • " }else{ fadeOut(); alert("用户已存在") } } } } loginIn.onclick = function () { //登录 var data2 = 'username=' + signIn["username"].value + '&' + 'pass=' + signIn["pass"].value; ajax('post','/signin',data2,"application/x-www-form-urlencoded"); xhr.onreadystatechange = function () { if(xhr.readyState==4&&xhr.status>=200&&xhr.status<300){ let text = JSON.parse(xhr.responseText).code; //服务器返回的对象 console.log(text); // document.getElementsByClassName('login')[0].outerHTML = "
  • "+signUp["username"].value+ "(=^ ^=)" +"
  • " if(text===1){ fadeOut(); // let imgTitle = document.getElementsByClassName('img-title')[0]; // imgTitle.setAttribute('src','/images/' + JSON.parse(xhr.responseText).avator) setTimeout(()=>{ window.location.reload(); },1000) }else if(text === 2){ alert('密码错误') }else{ alert('账号不存在') } } } }

    登录后复制

    footer.ejs

      

    登录后复制

    header为页面头部结构,nav为页面导航条,login为登录、注册内容、footer为页面顶部结构。可以看到我在ejs文件里有很多的if else 判断语句,这是根据session来判断用户是否登录渲染不同的内容。现在我们需要我们的页面编写样式:分别是home.css和index.css

    为了增强对原生js的理解,在项目里我用了大量的原生ajax(显然jquery封装的ajax比较好哈哈),因此这里先编写一个原生ajax请求:

    ajax.js

    var xhr = null; function ajax(method,url,data,types) { //封装一个ajax方法 // var text; if(window.XMLHttpRequest){  xhr = new XMLHttpRequest(); }else if(window.ActiveXObject){  xhr = new ActiveXObject("Microsoft.XMLHTTP"); }else {  alert('你的浏览器不支持ajax');  return false; }  xhr.onerror = function (err) {  alert("some err have hapened:",err); } xhr.open(method,url,true); if(method=="post"){  xhr.setRequestHeader("Content-type",types);  // xhr.setRequestHeader("Conent-Type",'application/json'"application/x-www-form-urlencoded") } try{  setTimeout(()=>{  xhr.send(data); },0); }catch(err) {  alert("some error have hapened in font:",err); } return xhr; }

    登录后复制

    实现登录注册

    前端基本页面开发好后,我们就可以写后台登录接口了:

    注册:signup.js

    var router = require('koa-router')();var userModel = require('../lib/mysql.js');var md5 = require('md5') // 注册页面  // post 注册router.post('/signup', async(ctx, next) => { console.log(ctx.request.body) var user = { name: ctx.request.body.username, pass: ctx.request.body.pass, repeatpass: ctx.request.body.repeatpass } let flag = 0; await userModel.findDataByName(user.name) .then(result => {  console.log(result)  if (result.length) {     //处理err   console.log('用户已存在')   ctx.body = {   code: 1   };      } else if (user.pass !== user.repeatpass || user.pass == '') {  ctx.body = { //应把这个逻辑放到前端   code: 2  };  } else {  flag = 1;      } }) if(flag==1){ let res = await userModel.insertData([user.name, md5(user.pass + 'asd&$BH&*') ]) console.log(res.insertId) await userModel.findDataByName(user.name) .then((result)=>{    // var res = JSON.parse(JSON.stringify(result))  console.log(result[0]['avator'])  ctx.session.id = res.insertId;  ctx.session.user=user.name;  ctx.session.avator = 'default.jpg';  ctx.body = {  code: 3  };  console.log('注册成功')  }) }})module.exports = router

    登录后复制

    密码采用md5加密,注册后为用户创建session并将其添加到数据库,写完别忘了在最后加上module.exports = router将接口暴露出来。

    登录:signin.js

    var router = require('koa-router')();var userModel = require('../lib/mysql.js')var md5 = require('md5')router.post('/signin', async(ctx, next) => { console.log(ctx.request.body) var name = ctx.request.body.username; var pass = ctx.request.body.pass; await userModel.findDataByName(name) .then(result => {  var res = JSON.parse(JSON.stringify(result))  if (name === res[0]['name']&&(md5(pass + 'asd&$BH&*') === res[0]['pass'])) {   console.log('登录成功')   ctx.body = {   code: 1,   }    ctx.session.user = res[0]['name']   ctx.session.id = res[0]['id']   ctx.session.avator = res[0]['avator']   }else if(md5(pass + 'asd&$BH&*') != res[0]['pass']){  ctx.body = {   code: 2 //密码错误  }  } }).catch(err => {  ctx.body = {  code: 3 //账号不存在+  }  console.log('用户名或密码错误!') })})module.exports = router

    登录后复制

    退出登录:signout.js

    //使用新建的路由文件//登录app.use(require('./routers/signin.js').routes())//注册app.use(require('./routers/signup.js').routes())//退出登录app.use(require('./routershttps://www.php.cn/signout.js').routes())

    登录后复制

    相信看了本文案例你已经掌握了方法,更多精彩请关注【创想鸟】其它相关文章!

    推荐阅读:

    vue-element做出音乐播放器功能(附代码)

    怎样使用vue实现个人信息查看与密码修改

    以上就是node+koa2+mysql+bootstrap搭建论坛前后端的详细内容,更多请关注【创想鸟】其它相关文章!

    版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

    发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2752995.html

    (0)
    上一篇 2025年3月8日 06:32:04
    下一篇 2025年2月24日 15:32:22

    AD推荐 黄金广告位招租... 更多推荐

    相关推荐

    • 利用live-server如何搭建本地服务器和自动刷新,具体方法有哪些?

      下面我就为大家分享一篇使用live-server快速搭建本地服务器+自动刷新的方法,具有很好的参考价值,希望对大家有所帮助。 1、安装 $ sudo npm install -g live-server 登录后复制 2、使用下面的命令会自动…

      编程技术 2025年3月8日
      200
    • 如何利用VuePress搭建个人博客

      这次给大家带来如何利用VuePress搭建个人博客,利用VuePress搭建个人博客的注意事项有哪些,下面就是实战案例,一起来看一下。 VuePress vuepress是尤大大4月12日发布的一个全新的基于vue的静态网站生成器,实际上就…

      2025年3月8日 编程技术
      200
    • 使用vue-cli如何快速搭建单页应用以及所遇到的问题和一些解决办法

      这篇文章主要介绍了详解vue-cli 快速搭建单页应用之遇到的问题及解决办法,现在分享给大家,也给大家做个参考。 一、报错内容类似:Expected indentation of 0 spaces but found 4 将 build 文…

      2025年3月8日 编程技术
      200
    • 如何使用JS实现前后端同构

      这次给大家带来如何使用JS实现前后端同构,使用JS实现前后端同构的注意事项有哪些,下面就是实战案例,一起来看一下。 什么是前后端同构 明确三个概念:「后端渲染」指传统的 ASP、Java 或 PHP 的渲染机制;「前端渲染」指使用 JS 来…

      编程技术 2025年3月8日
      200
    • JavaScript中的number的详细介绍

      本篇文章给大家带来的内容是关于javascript中的number的详细介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 声明:需要读者对二进制有一定的了解 对于 JavaScript 开发者来说,或多或少都遇到过 js…

      编程技术 2025年3月8日
      200
    • js是前端还是后端

      javascript是前端开发语言,是一种动态类型、弱类型、基于原型的语言;javascript经常与html、css技术一起构成前端开发,javascript一般通过ajax与后台进行数据交互。 本文操作环境:Windows7系统、Del…

      2025年3月8日
      200
    • PHP实现daemon – 后端

      TL;DR php实现守护进程可以通过 pcntl 与 posix 扩展实现。 编程中需要注意的地方有: 通过二次 pcntl_fork() 以及 posix_setsid 让主进程脱离终端通过 pcntl_signal() 忽略或者处理 …

      2025年3月7日
      200
    • windows本地搭建easy-mock环境教程

        起因:由于easy-mock官网很不稳定,所以想搭建自己本地的mock环境(当然公司有可用的服务器给你用直接部署到服务器上更好),然鹅没有申请下来或没服务器的先在本地搭一个,用着吧。emm。。。。。 1、首先安装node.js 环境 (…

      2025年3月7日 编程技术
      200
    • javascript是前端还是后端

      javascript是前端。javascript是前端开发语言,经常与html、css技术一起构成前端开发;它一般通过ajax与后台进行数据交互。JavaScript是一种属于网络的脚本语言,常用来为网页添加各式各样的动态功能。 本教程操作…

      2025年3月7日
      200
    • 聊聊Node中的异步实现与事件驱动

      本篇文章带大家了解一下node中的异步实现与事件驱动,希望对大家有所帮助! Node的特点 计算机中的一些任务一般可以划分为两个类别,一个类别叫做IO密集型,一个叫做计算密集型;对于计算密集型的任务,只能不断榨干CPU的性能,但是对于IO密…

      2025年3月7日 编程技术
      200

    发表回复

    登录后才能评论