node后端博客

node 博客项目

创建后端服务器

  • 先创建一个nodejs文件,

  • 使用npm -y init 快速生成package.json文件,方便管理插件

  • 使用npm install express命令下载第三方模块,可以快速创建一个本地服务器

 //使用模块前必须先导入
 const express = require('express')
 //调用express函数返回的对象,便可快速创建本地服务器
 const app = express()
 //绑定端口,这样就已经创建好了一个本地服务器,可以通过http://localhost:3000访问
 app.listen(3000)

连接数据库

  • 使用npm install mongoose可以连接mongodb数据库

  • 使用mongoos中的connect方法可以连接数据库

 //导入mongoo模块
 const mongoose = require('mongoose')
 //如果数据库没有设置了登陆验证,user、password可以省略
 //27017是数据库端口号,可省略
 //dbname是你要连接的数据库名称
 //返回的结果是一个promise对象
 mongoose.connect('mongodb:user:password@localhost:27017/dbname'
 //第二个参数是一个对象,如果不加会弹出警告,但是不影响使用
 { useNewUrlParser: true, useUnifiedTopology: true }).then(()=>{
 console.log('连接数据库成功')
 })
创建集合规则
  • 集合规则就相当于对数据库中各个字段要求的规范

  • 使用 new mongoose.Schema 可以创建集合

  • 这个函数接收的参数是一个对象

  //创建用户集合规则
  const userSchema = new mogoose.Schema({
      name:{
        	//传入的name字段必须是字符串类型  
          type:String
          //表示改字段为必填属性
          required:true
      },
      password: {
          type: String,
          required: true
      },
      email: {
          type: String,
          required: true
      },
      role: {
          type: String,
          //default表示默认值
          default: 'normal'
      },
      createDate: {
          type: String,
          default: new Date
      }
  },
  	{
      //如果不加这个参数,在数据库中会多出一个_v字段
        versionKey: false
    }
 )
创建用户集合
  • 使用上一步创建好的用户集合规则可以创建用户集合

  • 使用mongoose.model方法可以创建用户集合

 //第一个参数为要创建的数据库名称
 //第二个参数是要使用的集合规则
 //第三个参数可以省略,但是省略或创建的数据库名称会改变 User => users
 //第三个参数可以强制规定数据库的名字,建议加上
 const User = mongoose.model('User',userSchema,'users')
用户密码加密
  • 使用第三方模块bcrypt来加密用户密码以及密码比对

  • npm install bcrypt下载安装后使用require引入

    • const bcrypt = require(‘bcrypt’)

  • 加密密码主要有三个步骤

    • 生成加密盐

      • const salt = await bcrypt.genSalt(10)

    • 密码加密

      • const pwd = await bcrypt.hash(‘admin’, salt)

    • 替换用户密码

  • ; (async () => {
        // 引入密码加密插件
        const bcrypt = require('bcrypt')
        // 密码加密盐
        const salt = await bcrypt.genSalt(10)
        const pwd = await bcrypt.hash('admin', salt)
     })()
    
    //这个加密插件返回的都是promis对象,可以用异步函数的形式来简化操作
    
    创建用户
  • 使用用户集合中的create方法便可以创建用户

//create函数接收一个对象为参数
//这个对象的内容就是集合规则中规定的字段
//返回的是一个promis对象
User.create({
    name:'张三',
    //生成后的加密密码
    password:pwd,
    email:'zhangsan@qq.com',
    role:'admin'
}).then(()=>{
    console.log('创建用户成功')
})
//建议在使用一次后就注释这个代码,不然每次启动项目就会创建这个用户
  • 数据库的操作可以写在另一个文件中,与创建服务器文件分开,方便管理,使用model.exprots导出用户集合函数便可

vue脚手架创建前端项目

  • 使用npm install -g @vue/cli全局下载安装vue脚手架工具
  • 完成后,可以使用vue create 项目名字vue ui两种方式来创建项目
  • vue 创建项目,见另一篇博客
引入ElementUI
  • 使用 npm i element-ui -S安装项目
  • 在前端项目main.js入口文件中引入样式文件import 'element-ui/lib/theme-chalk/index.css'
  • 在和main.js文件平级的目录下可以创建一个ElementUI.js文件,按需导入组件,然后在main.js中导入便可
安装axios
  • 使用命令npm install axios安装axios

  • 安装完成后,在main.js文件中导入

    • ​ import axios from ‘axios’

  • 配置axios默认请求路径(可省略,但写请求路径是会更麻烦)

    • ​ //这个地址就是服务器端访问的地址

      axios.defaults.baseURL = ‘http://localhost:3000’

  • 设置发送请求时携带请求头

    • axios.defaults.withCredentials = true

  • 在全局中挂载axios

    • Vue.prototype.$http = axios

      //下次使用时,只需要this.$http

登陆

####前端页面

在这里插入图片描述

  • 使用ElementUI中的el-card组件,可以快速布局

  • 使用el-form组件可以快速生成一个表单

    • Form 组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可

    • 	<el-form
              :model="ruleForm"
              :rules="rules"
              ref="ruleForm"
              label-width="100px"
              class="demo-ruleForm"
              hide-required-asterisk
            >
              <el-form-item label="用户邮箱" prop="email">
                <el-input v-model="ruleForm.email"></el-input>
              </el-form-item>
              <el-form-item label="用户密码" prop="password">
                <el-input v-model="ruleForm.password" type="password"></el-input>
              </el-form-item>
            </el-form>
            <div class="btnBox">
              <el-button type="primary" size="large" @click="login()">登陆</el-button>
              <el-button type="info" size="large" @click="resetFrom()">重置</el-button>
            </div>
       <script>
            export default {
      	data() {
        			return {
          			 ruleForm: {
              				 email: '',
                			password: ''
            					},
            					rules: {
                              email: [{ required: true, message: '请输入邮箱' }],
                              password: [{ required: true, message: '请输入密码' }]
                            }
                           }
                          },
               methods: {
                 resetFrom() {
                      this.$refs.ruleForm.resetFields()
                       },
                       login() {
                       //表单预校验    
                        this.$refs.ruleForm.validate(async valid => {
                         if (!valid) return
                        //发送请求    
                         const { data } = await this.$http.post('/admin/login',this.ruleForm)
                         if (data.status !== 200) {
                            return this.$message({
                               type: 'error',
                                 message: data.msg
                                 })
                                }
                           this.$message({
                                type: 'success',
                                 message: `登陆成功,欢迎您${data.user.name}`
                                 })
               window.sessionStorage.setItem('token', data.token)
               window.sessionStorage.setItem('username', data.user.name)
                this.$router.push('/admin/welcome')
                                  })
                              }
                          }
                        }
        	</script> 
      
后台服务器
  • app.js文件中创建好服务器后,我们需要设置跨域请求

    • // 设置跨域和相应数据格式
      app.all('*', function (req, res, next) {
          res.header('Access-Control-Allow-Origin', 'http://localhost:8081')
          res.setHeader("Access-Control-Allow-Credentials", "true")
          res.header('Access-Control-Allow-Headers', 'X-Requested-With, mytoken')
          res.header('Access-Control-Allow-Headers', 'X-Requested-With, Authorization')
          res.setHeader('Content-Type', 'application/json;charset=utf-8')
          res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length, Authorization, Accept,X-Requested-With')
          res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
          res.header('X-Powered-By', ' 3.2.1')
          // if (req.method == 'OPTIONS') res.send(200)
          // /*让options请求快速返回*/ else
          next()
      })
      
  • 在与app.js文件平级的目录下我们可以创建一个router文件夹,来管理所有的路由文件

  • app.js全局挂载express-session插件

    • npm install express-session //安装

    • // 引入express-session模块
      const session = require('express-session')
      // 只要http请求有insurance就会创建session
      app.use(session({
          store: new FileStore(),//数据持久化方式,这里表示本地文件存储
      	//加密方式    
          secret: 'secret key',
          resave: true,
          rolling: true,
          saveUninitialized: false,
          //过期时间,单位毫秒
          cookie: {
              maxAge: 3000 * 60 * 60
          }
      }))
      
  • router文件夹下创建一个login.js文件,用来管理与登陆相关的路由及代码

    • 引入express模块后,用express.Router()方法来创建模块化路由对象

      • const express = require(‘express’)

        const login = express.Router()

    • 拦截路由请求

      • login.post(’/login’,(req,res)=>{})

    • 使用第三方模块bodyParse,可以解析表单请求对象

      • npm install bodyParse //安装

      • app.js中全局挂载

      • // 拦截post请求,挂载req.body

        app.use(bodyParser.urlencoded({ extended: false }))

        // 如果不设置bodyParser.json()就接收不到axios发送的json数据请求

        app.use(bodyParser.json())

    • // 引入express插件
      const express = require('express')
      let login = express()
      // 引入密码解密插件
      const bcrypt = require('bcrypt')
      // 引入数据库User
      const { User } = require('../../db/index')
      // 拦截来自‘/login’的post请求
      login.post('/login', async (req, res) => {
          const userInfo = req.body
          // console.log(userInfo);
      
          const user = await User.findOne({ email: userInfo.email })
          // console.log(user);
          if (!user) {
              res.send({ msg: '用户邮箱或密码错误', status: 400 })
              return
          } else {
              // console.log(await (bcrypt.compare(userInfo.password, user.password)));
              if (! await (bcrypt.compare(userInfo.password, user.password))) {
                  return res.send({ msg: '用户名或密码错误', status: 400 })
              } else {
                  // 返回用户信息,状态码,sessionID用来做数据保护,下次请求没有这个ID请求不成功
                  // console.log(req.session);
                  // console.log(req.sessionID);
                  req.session.flag = true
                  res.send({ user, status: 200, token: req.sessionID })
              }
          }
      })
      //导出这个函数
      module.exports = { login }
      
    • app.js文件中设置中间件拦截请求

      • const {login} =require('./router/login')
        app.use('/login',login)
        
<think>好的,用户现在想了解使用Node.js作为博客项目后端技术的可行性或最佳实践。之前用户询问过博客后端技术选型,我推荐了Java Spring Boot、Python Django之类的选项,但用户现在特别关注Node.js,可能是因为他们看到了站内引用的相关内容,或者对JavaScript生态系统比较熟悉。需要结合之前的回答和引用中的信息来给出面的建议。 首先,用户提到的三个引用都涉及Node.js的应用。引用[1]提到Node.js的高性能和事件驱动模型,适合处理并发请求,这对博客的高并发场景有帮助。引用[2]讨论了使用Express.js的结构化项目,这对代码组织和可维护性很重要。引用[3]展示了一个简易后端项目的代码,包括处理POST数据和数据库连接,这可以作为实现的具体参考。 我需要比较之前推荐的Java/Python方案和Node.js的优劣。Node.js的优势在于非阻塞I/O、JavaScript、丰富的npm生态,适合I/O密集型应用。而Java更适合复杂的业务逻辑和事务处理。用户可能关心性能、开发效率、维护成本等方面。 接下来要考虑最佳实践。根据引用中的内容,项目结构、中间件使用、异步处理、数据库集成、身份认证、部署等都是关键点。例如,引用[2]提到代码结构的重要性,应该建议遵循MVC模式,合理分目录。引用[3]中的代码示例如何处理POST数据和数据库操作,可以推荐使用ORM如Sequelize或Mongoose,而避免手动处理SQL拼接,以提高安性和效率。 另外,用户之前的问题中提到了MySQL和Redis的使用,所以在Node.js方案中也需要包括这些组件的整合,比如使用mysql2库连接MySQL,使用ioredis连接Redis。同时,安方面需要考虑JWT认证、输入验证、防止SQL注入等,引用[1]中的JWT和Spring Security在Node.js中可以用Passport.jsjsonwebtoken库替代。 部署方面,之前建议使用Nginx、Docker等,同样适用于Node.js。需要提到PM2作为进程管理工具,保证应用稳定运行。监控和日志也是必要的,可以使用Winston或Morgan记录日志,Prometheus监控性能。 可能还需要比较Node.js和其他技术的优劣,比如开发速度更快,适合小到中型项目,但可能不适合CPU密集型任务。如果用户预期有高并发或实时需求,Node.js会更合适。 最后,用户可能希望知道具体的步骤或示例代码,比如如何设置Express项目结构,如何连接数据库,实现路由等,这需要给出简洁的示例,如引用[3]中的代码片段,但建议使用更现代的语法或框架特性,比如async/await代替Promise链,使用中间件处理请求等。 总结起来,回答需要涵盖可行性分析(优势)、最佳实践(项目结构、技术选型、安、性能优化)、示例代码、部署方案,以及与之前推荐技术的对比,帮助用户面理解Node.js博客项目中的应用。</think>根据技术特性与博客项目需求,使用Node.js构建博客后端是可行且高效的选择。以下从技术优势、实现方案、最佳实践三个维度进行说明: --- ### 一、Node.js的核心优势 1. **高性能并发处理** - 事件驱动与非阻塞I/O模型,单线程处理高并发请求 $$ \text{QPS} = \frac{\text{最大并发连接数}}{\text{平均请求处理时间}} $$ 实测Express框架可轻松支撑5000+ QPS[^1] 2. **一致性** - 前端React/Vue后端共用JavaScript语言,降低开发成本 - 统一JSON数据格式处理请求响应 3. **生态体系成熟** - npm仓库提供超过200万模块,如Express、Koa、NestJS等框架 - 支持MySQL/MongoDB/Redis等主流数据库驱动 --- ### 二、典型技术方案 #### 1. 框架选型建议 | 框架类型 | 推荐方案 | 适用场景 | |------------|--------------|-------------------------| | 轻量级 | Express.js | 小型博客/快速原型开发[^2] | | 结构化 | NestJS | 企业级博客/需要严格架构规范 | | 功能 | AdonisJS | 自带ORM/认证等完整功能的博客系统 | #### 2. 项目结构规范 ```bash project/ ├── config/ # 环境配置 ├── src/ │ ├── controllers # 请求处理层 │ ├── services # 业务逻辑层 │ ├── models # 数据模型层 │ ├── routes # 路由定义 │ ├── middleware # 认证/日志等中间件 │ └── utils # 工具函数 ├── test/ # 单元测试 └── app.js # 入口文件 ``` #### 3. 关键技术实现 **数据库操作示例(Sequelize ORM)**: ```javascript // models/Blog.js const { DataTypes } = require('sequelize'); module.exports = (sequelize) => { return sequelize.define('Blog', { title: DataTypes.STRING, content: DataTypes.TEXT, authorId: DataTypes.INTEGER }); }; // controllers/blogController.js const getBlogList = async (req, res) => { try { const blogs = await Blog.findAll(); res.json({ code: 200, data: blogs }); } catch (err) { res.status(500).json({ code: 500, message: err.message }); } }; ``` --- ### 三、最佳实践指南 1. **性能优化** - 使用`cluster`模块充分利用多核CPU - 通过Redis缓存高频查询(如热门文章列表) ```javascript // 缓存中间件示例 const cacheMiddleware = (req, res, next) => { const key = req.originalUrl; redis.get(key, (err, data) => { if (data) return res.json(JSON.parse(data)); next(); }); }; ``` 2. **安防护** - 使用`helmet`设置HTTP安头 - 通过`express-validator`校验请求参数 ```javascript app.post('/blog', body('title').isLength({ min: 5 }), (req, res) => { const errors = validationResult(req); if (!errors.isEmpty()) { return res.status(400).json({ errors: errors.array() }); } // 安处理逻辑 } ); ``` 3. **部署方案** - 使用PM2管理进程:`pm2 start app.js -i max` - Nginx反向代理配置: ```nginx server { listen 80; location / { proxy_pass http://localhost:3000; proxy_set_header Host $host; } } ``` --- ### 四、对比其他技术 | 指标 | Node.js | Spring Boot | Django | |-------------|--------------|--------------|--------------| | 学习曲线 | 低(JS基础即可) | 中(需Java基础) | 中(Python基础) | | 并发处理能力 | ★★★★☆ | ★★★☆☆ | ★★☆☆☆ | | 生态丰富度 | ★★★★★ | ★★★★☆ | ★★★☆☆ | | 适合场景 | I/O密集型应用 | 复杂业务系统 | 快速原型开发 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值