{"id":17312690,"url":"https://github.com/buuing/express-blog","last_synced_at":"2026-05-09T00:37:21.172Z","repository":{"id":109592494,"uuid":"139590119","full_name":"buuing/express-blog","owner":"buuing","description":"使用 Node.js + MySQL 搭建论坛 (自娱项目)","archived":false,"fork":false,"pushed_at":"2018-09-21T14:24:15.000Z","size":124,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-27T01:15:52.326Z","etag":null,"topics":["mysql","nodejs"],"latest_commit_sha":null,"homepage":"","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/buuing.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-03T13:48:01.000Z","updated_at":"2021-12-20T10:29:53.000Z","dependencies_parsed_at":"2023-03-21T21:33:28.344Z","dependency_job_id":null,"html_url":"https://github.com/buuing/express-blog","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/buuing/express-blog","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buuing%2Fexpress-blog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buuing%2Fexpress-blog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buuing%2Fexpress-blog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buuing%2Fexpress-blog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/buuing","download_url":"https://codeload.github.com/buuing/express-blog/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/buuing%2Fexpress-blog/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32803621,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"ssl_error","status_checked_at":"2026-05-08T08:22:45.650Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mysql","nodejs"],"created_at":"2024-10-15T12:44:19.505Z","updated_at":"2026-05-09T00:37:21.157Z","avatar_url":"https://github.com/buuing.png","language":"CSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003e git clone https://github.com/buuing/express-blog.git\n\n`npm install`\n\n`npm run dev`\n\n`127.0.0.1:8080`\n\n---\n\n\u003cbr\u003e\n\n## 项目描述\n\n使用node.js搭建一个类似于论坛社区的门户网站，在这里用户可以进行登陆注册等一系列相关操作，登陆成功后可以发帖、评论、删除文章等...\n\n\u003cbr\u003e\n\n## 项目介绍\n\n使用express框架来构建node项目\n\u003e `npm i express`\n\n```\n// 加载模块\nconst express = require('express')\n// 创建服务器实例\nconst app = express()\n```\n\n---\n\n使用art-template模板引擎渲染页面和数据\n\u003e `npm i art-template express-art-template`\n\n```\n// 如果需要渲染ajax请求来的数据, 则需要删除\u003c%= %\u003e语法规则\nrequire('art-template').defaults.rules.shift()\n// 配置模板引擎\napp.engine('html', require('express-art-template'))\n```\n\n然后在前端引入web\n\n---\n\n使用内置中间件开放静态资源目录\n```\n// 开放静态资源目录\napp.use('/node_modules', express.static('./node_modules/'))\napp.use('/public', express.static('./public/'))\n```\n\n---\n\n使用router进行路由管理\n```\n// 创建路由实例\nconst router = express.Router()\n// 挂载路由容器到app中,使路由生效\napp.use(router)\n```\n\n---\n\n使用body-parser处理表单请求\n\u003e `npm i body-parser`\n\n```\n// 配置 body-parser\napp.use(bodyParser.urlencoded({ extended: true }))\n// app.use(bodyParser.json())\n```\n\n---\n\n使用mysql数据库模块来处理数据交互\n\u003e `npm i mysql`\n\n```\n// 加载mysql模块\nconst mysql = require('mysql')\n// 创建连接池\nconst pool = mysql.createPool(dbConfig)\n// 封装私有的执行sql方法\nexports.query = (...args) =\u003e {\n  const callback = args.pop()\n  // 从连接池中获取连接\n  pool.getConnection((err, connection) =\u003e {\n    if (err) {\n      return callback(err, undefined)\n    }\n    // 执行sql语句\n    connection.query(...args, (...results) =\u003e {\n      // 释放连接\n      connection.release()\n      // .\n      callback(...results)\n    })\n  })\n}\n```\n\n---\n\n使用MD5进行数据加密\n\u003e `npm i blueimp-md5`\n\n```\n// 加载MD5模块\nconst md5 = require('blueimp-md5')\n// 数据加密\ndata.password = md5(data.password)\n```\n\n---\n\n使用session存储用户登录状态,并使用express-mysql-session持久化存储登录状态\n\u003e `npm i express-session express-mysql-session`\n\n```\n// 加载session模块\nconst session = require('express-session')\nconst MySQLStore = require('express-mysql-session')(session)\n// 配置信息\nconst options = {\n  host: '127.0.0.1',\n  port: 3306,\n  user: 'root',\n  password: '1234',\n  database: 'test'\n}\n// 配置session开启会话\napp.use(session({\n  // 自定义加密字符串\n  secret: 'buuing.com',\n  // 持久化存储\n  store: sessionStore,\n  // 配置cookie\n  cookie: {\n    // 过期时间(单位为毫秒)\n    maxAge: 1000*60*60*12*1\n  },\n  resave: false,\n  // 使用session才会配发秘钥\n  saveUninitialized: false\n}))\n\n// 添加用户登录状态\nreq.session.user = user\n```\n\n---\n\n使用app.use中间件处理错误\n```\n// 配置错误处理中间件\napp.use((err, req, res, next) =\u003e {\n  res.status(500).send({\n    error: err.message\n  })\n})\n```\n只需要在后面的函数中`return next(err)`即可\n\n---\n\n使用app.locals全局模板对象,来存储session中的用户信息\n```\napp.use((req, res, next) =\u003e {\n  app.locals.user = req.session.user\n})\n```\n\n---\n\n使用jquery-form处理表单数据\n\u003e `npm i jquery-form`\n\n```\n$('#form').on('submit', function (e) {\n  e.preventDefault()\n  $(this).ajaxSubmit((res) =\u003e {\n    console.log(res)\n  })\n})\n```\n\n---\n\n使用moment时间类库处理时间\n\u003e `npm i moment`\n\n```\n// 加载moment模块\nconst moment = require('moment')\n// 调用\nmoment().format('YYYY-MM-DD HH:mm:ss')\n```\n\n---\n\n使用第三方中间件response-time记录响应时间\n\u003e `npm i response-time`\n\n```\n// 加载模块\nconst responseTime = require('response-time')\n// 会自动在http响应头中加入响应时间相关信息\napp.use(responseTime())\n```\n\n---\n\n使用esLint代码风格强校验工具\n\u003e `npm i eslint nodemon --save-dev`\n\u003e `./node_modules/.bin/eslint --init`\n\n在package.json文件中加入如下代码, 使每次重启服务器都进进行一次代码校验\n```\n\"scripts\": {\n  \"prestart\": \"eslint ./\",\n  \"start\": \"node ./app.js\",\n  \"dev\": \"nodemon --exec npm start\"\n},\n```\n\n---\n\n使用bootstrap和jquery渲染css样式布局和数据交互\n\u003e `npm i bootstrap@3.3.7 jquery`\n\n\u003cbr\u003e\n\n## 目录结构\n\n- controller 控制器\n- middlewares 中间件模块\n- models 模型\n- node_modules 第三方模块\n- public 静态资源\n- routes 路由模块\n- view 视图\n- .gitignore 忽略文件\n- app.js 入口文件\n- config.js 配置文件\n- ithub.sql 数据表信息\n- package-lock.json\n- package.json\n- README.MD 说明文件\n\n\u003cbr\u003e\n\n## 路由设计\n\n| 请求方式 | 请求路径 | 说明\n| ------ | --------- | ----\n| GET    | /         | 渲染首页\n| GET    | /login    | 渲染登录页\n| POST   | /login    | 处理登录请求\n| GET    | /register | 渲染注册页\n| POST   | /register | 处理注册请求\n| GET    | /logout   | 处理退出请求\n| GET    | /topic/create        | 渲染文章发布页面\n| POST   | /topic/create        | 处理文章发布请求\n| GET    | /topic/:topicId      | 渲染文章页面\n| GET    | /topic/:topicId/edit | 渲染文章修改页面\n| POST   | /topic/:topicId/edit | 处理文章修改请求\n| POST   | /topic/:topicId/del  | 处理文章删除请求\n| GET    | /topic/:topicId/comment                 | 获取所有评论\n| POST   | /topic/:topicId/comment                 | 发表评论\n| GET    | /topic/:topicId/comment/:commentId/edit | 获取编辑评论内容\n| POST   | /topic/:topicId/comment/:commentId/edit | 处理编辑请求\n| POST   | /topic/:topicId/comment/:commentId/del  | 处理删除请求\n\n\u003cbr\u003e\n\n## 数据库设计\n\n```\nSET FOREIGN_KEY_CHECKS=0;\n```\n\n### 用户表\n\n```\nDROP TABLE IF EXISTS `users`;\nCREATE TABLE `users` (\n  `id` int(11) NOT NULL AUTO_INCREMENT,\n  `email` varchar(50) NOT NULL,\n  `password` varchar(50) NOT NULL,\n  `nickname` varchar(20) NOT NULL,\n  `avatar` varchar(100) DEFAULT NULL,\n  `bio` varchar(100) DEFAULT '',\n  `gender` bit(1) DEFAULT NULL,\n  `birthday` date DEFAULT NULL,\n  `isDeleted` bit(1) DEFAULT b'0',\n  `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n  `updatedAt` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB AUTO_INCREMENT=68 DEFAULT CHARSET=utf8;\n```\n\n### 文章表\n\n```\nDROP TABLE IF EXISTS `topics`;\nCREATE TABLE `topics` (\n  `id` int(11) NOT NULL AUTO_INCREMENT,\n  `title` varchar(255) NOT NULL,\n  `content` longtext NOT NULL,\n  `categoryId` int(11) DEFAULT NULL,\n  `userId` int(11) NOT NULL,\n  `createdAt` timestamp NOT NULL,\n  `updatedAt` timestamp NOT NULL,\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB AUTO_INCREMENT=172 DEFAULT CHARSET=utf8;\n```\n\n### 文章分类表\n\n```\nDROP TABLE IF EXISTS `topic_categories`;\nCREATE TABLE `topic_categories` (\n  `id` int(11) NOT NULL AUTO_INCREMENT,\n  `name` varchar(255) NOT NULL,\n  `createdAt` timestamp NOT NULL,\n  `updatedAt` timestamp NOT NULL,\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;\n```\n\n### 评论表\n\n```\nDROP TABLE IF EXISTS `topic_comments`;\nCREATE TABLE `topic_comments` (\n  `id` int(11) NOT NULL AUTO_INCREMENT,\n  `content` varchar(255) NOT NULL,\n  `userId` int(255) NOT NULL,\n  `topicId` int(255) NOT NULL,\n  `createdAt` timestamp NOT NULL,\n  `updatedAt` timestamp NOT NULL,\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n```\n\n\u003cbr\u003e\n\n## Bug汇总\n\n#### Bug NO.1\n\n- 问题描述：\n\n\u003e 控制器中的`req.body`始终获取不到前端ajax发送过来的数据，页面中console.log打印表单数据有值，但客户端post过来之后，服务端却一直显示undefined\n\n- 解决方案：\n\n\u003e 将挂载路由的代码`app.use(router)`放到所有的配置代码后面\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuuing%2Fexpress-blog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbuuing%2Fexpress-blog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuuing%2Fexpress-blog/lists"}