传统开发模式做项目:手把手教你,直击实战项目。

Posted 贪吃ღ大魔王

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了传统开发模式做项目:手把手教你,直击实战项目。相关的知识,希望对你有一定的参考价值。

传统开发模式做项目

使用模板引擎,在静态页面中书写js逻辑,所以项目中需要使用模板引擎

步骤:

  1. 将做的项目src放到project中

    在project中 进行项目初始化

    npm init -y
    
  2. 下载依赖的模块:需要用到的

    npm i express art-template express-art-template cookie-parser body-parser bcryptjs mysql svg-captcha
    
  3. 就在src所在文件夹中新建app.js用来创建服务器

    // 创建服务器
    const express = require('express')
    const app = express()
    app.get('/',(req,res)=>
        res.send('服务器搭建成功')
    )
    app.listen(3000)
    
  4. 在package.json文件中配置启动项目的命令:

    "scripts": 
        "test": "echo \\"Error: no test specified\\" && exit 1",
        "start":"nodemon app.js"
    ,
    

  1. 启动服务器

    npm start
    

    再打开浏览器测试:http://localhost:3000

    服务器就搭建成功了…

  2. 静态资源托管:

    app.use('/src', express.static('src'))
    

    打开浏览器:就可以访问项目的index.html

  3. 设置模板引擎,处理 / 路由请求的时候,将首页的html模板渲染到浏览器中

    配置模板引擎:

    因为需要用到path ,先导入

    const path = require('path')
    

    然后配置模板引擎

    // 配置模板引擎
    app.engine('html',require('express-art-template'))
    app.set('views',path.join(__dirname,"template"))
    app.set('view engine','html')
    

    处理 / 路由渲染index模板:

    需要将 res.end改为 res.render

    // 处理首页
    app.get('/',(req,res)=>
        res.render("index")
    )
    

    但是,现在在template模板文件夹下没有index这个模板,所以,从src中将index.html剪切到了template文件夹下了

    测试访问 :http://localhost:3000

    home.html中的标签能显示,但是js和css以及img都没有。

    查看这些静态资源的路径:

    • normalize.css的路径:/node_modules/normalize.css/normalize.css

    • bootstrap的路径:/node_modules/bootstrap/dist/css/bootstrap.min.css

    • jquery的路径:/node_modules/jquery/dist/jquery.min.js

    • layer的路径:/node_modules/layui-layer/dist/layer.js

      上面的路径都是由/node_modules开头的,一次性处理掉

      定义中间件:

      // 处理 /node_modules开头的路由
      app.use('/node_modules',nodeModuleRotuer)
      

      处理这个请求的路由模块nodeModuleRotuer不存在,导入他

      const nodeModuleRotuer = require('./router/nodeModule.js')
      

      对应的文件还不存在,在src所在文件夹中新建了router文件夹,在这个router文件夹下,新建了nodeModule.js文件:

      const express = require('express')
      const router = express.Router()
      // 只要是经过前面的中间件 /node_modules来到这里的,只要是使用 /node_modules开头的路径,我们在这里处理
      router.use('/',(req,res)=>
      	// 具体处理应该是读取对应的文件并响应出去
          // 并没有这些文件 - jquery、normalize.css、layer这些文件,我们还没有下载
      )
      module.exports = router
      

      先下载项目中依赖的模块:

      npm i jquery bootstrap@3 layui-layer normalize.css
      

      下载好以后,就可以读取了

      然后再对这些路由进行响应处理 nodeModule.js

      const express = require('express')
      const router = express.Router()
      const fs = require('fs')
      // 只要是经过前面的中间件 /node_modules来到这里的,只要是使用 /node_modules开头的路径,我们在这里处理
      router.use('/',(req,res)=>
          // console.log(req.url);
          // 判断要读取的文件是否存在
          let bool = fs.existsSync('./node_modules'+req.url)
          if(!bool)
            throw new Error('文件不存在')
          
        // 读取并响应
          let data = fs.readFileSync('./node_modules' + req.url)
        res.end(data)
      )
      module.exports = router
      

    现在,有些项目中引入的node_modules中的资源就能响应成功了

    但是还有一些放在css、img、js文件夹中的资源还不能出现,应该是能出现的

    因为,我们做了静态资源托管了,分析:

    项目中引入的css和js这些资源,都是 ./开头的,但是静态资源托管要使用/src请求开头,所以需要修改静态资源托管:虚拟目录去掉

      // 静态资源托管
      app.use(express.static('src'))
    

    这样的话,当我们在浏览器中访问静态资源就能出现了

  4. 同样的道理,其他html文件,也需要通过模板引擎渲染显示,所以我们需要将其他html文件都剪切到template文件夹下

  5. 模块化开发 - 将所有请求的处理交给express中的路由模块去处理

    需要在app.js中,继续定义中间件,将所有请求先交给一个路由模块去处理

    const responseRouter = require('./router/response')
    
    // 通过路由模块处理所有的请求
    app.use('/',responseRouter)
    

    但是这样会跟前面处理node_modules请求的中间件发生冲突:

    下面的 / 会把 /node_modules拦截

    app.use('/node_modules',nodeModuleRotuer)
    
    app.use('/',responseRouter)
    

    所以,我们在app.js中只保留 / 路由模块处理,将 /node_modules的处理交给 / 处理的模块去操作

    app.use('/',responseRouter)
    

  6. 将所有请求都交给responseRouter去处理

  7. response.js中,作为总路由,去分配,每个路径请求过来,应该交给那个路由模块去处理:

    // 创建路由模块
    const express = require('express')
    const router = express.Router()
    const nodeModuleRouter = require('./nodeModule')
    const indexRouter = require('./index')
    // 先处理 /node_modules开头的请求
    router.use('/node_modules',nodeModuleRouter)
    // 处理首页
    router.use('/',indexRouter)
    module.exports = router
    

  8. 每个模块去处理一个请求

    nodeModule.js中处理 /node_modules开头的请求:

    const express = require('express')
    const router = express.Router()
    const fs = require('fs')
    // 只要是经过前面的中间件 /node_modules来到这里的,只要是使用 /node_modules开头的路径,我们在这里处理
    router.use('/',(req,res)=>
        // console.log(req.url);
        // 判断要读取的文件是否存在
        let bool = fs.existsSync('./node_modules'+req.url)
        if(!bool)
            throw new Error('文件不存在')
        
        // 读取并响应
        let data = fs.readFileSync('./node_modules' + req.url)
        res.end(data)
    )
    module.exports = router
    

    index.js中处理 / 开头的路径请求

    const express = require('express')
    const router = express.Router()
    // 处理首页
    router.get('/',(req,res)=>
        res.render('index')
    )
    module.exports = router
    

    此时打开:http://localhost:3000/ 处理成功

    多路由使用同一个模块处理:

    router.use(/(^\\/$)|(^\\/home$)|(^\\/index$)/,indexRouter)
    

都可以正常访问了

  1. 添加异常处理中间件:为了更好的用户体验

    // 在最下面添加异常处理中间件
    app.use((err,req,res,next)=>
        // 异常处理,不给用户显示具体的错误,就给用户显示一个错误的页面
        res.render('error')
    )
    

    现在这个error模板并不存在,所以需要在template文件中新建一个模板 error.html

    新建了一个错误的模板:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>document</title>
    </head>
    <body>
    <h1>发生了错误</h1>
    <p>发生错误了,很抱歉!!!</p>
    <p>请回到首页重新尝试:<a href="/">首页</a></p>
    </body>
    <script>
    
    </script>
    </html>
    

  2. 添加404中间件

    // 404中间件
    app.use((req,res,next)=>
        res.status(404).render('404')
    )
    

    现在这个404模板也不存在,所以需要在template文件中新建一个模板 404.html

    404模板:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>document</title>
    </head>
    <body>
    <h1>404页面不存在</h1>
    <p>请检查请求地址是否正确!!!</p>
    <p>请回到首页重新尝试:<a href="/">首页</a></p>
    </body>
    <script>
    
    </script>
    </html>
    

  3. 跟上面响应首页的时候一样,将别的页面也渲染出来,在response.js中,导入路由模块,处理路径

    const loginRouter = require('./login')
    const registerRouter = require('./register')
    const listRouter = require('./list')
    const detailRouter = require('./detail')
    const cartRouter = require('./shopping')
    // 先处理 /node_modules开头的请求
    router.use('/node_modules',nodeModuleRouter)
    // 处理首页
    // router.use('/',indexRouter)
    // router.use('/home',indexRouter)
    router.use(/(^\\/$)|(^\\/home$)|(^\\/index$)|(^\\/home.html$)/,indexRouter)
    // 处理登录页面
    router.use('/login.html',loginRouter)
    // 处理注册页面
    router.use('/register.html',registerRouter)
    router.use('/list.html',listRouter)
    router.use('/detail.html',detailRouter)
    router.use('/shopping.html',shoppingRouter)
    

    处理其他api路由

  4. 处理其他ajax请求,我们现在所有的ajax请求的路径,都是 /api/XXX,我们通过response.js中分发路由,将所有ajax请求,交给一个文件去处理 - api.js - api.js也是负责分发路由,交给每一个单独的模块去处理

    const regHandlerRouter = require('./regHandler')
    const logHandlerRouter = require('./logHandler')
    // 处理注册逻辑
    router.post('/register',regHandlerRouter)
    router.post('/login',logHandlerRouter)
    

    为了所有的ajax请求都能获取到post数据,所以在api.js中,所有逻辑处理之前,添加bodyParser中间件

    const bodyParser = require('body-parser')
    // 添加获取post数据的中间件
    router.use(bodyParser.urlencoded(extended:false))
    

    regHandler.js

    注册逻辑:

    是否被注册,操作mysql注册用户信息

    router.post('/', async (req, res) => 
        // 获取post数据
        let result = await select('select * from user where username="' + req.body.username + '"')
        if (result.length) 
            // 如果注册过,用户名被占用
            response(res, 2, '用户名被占用')
         else 
            //如果没有注册过,添加到数据库
            let bool = await cud('insert user(username,password,email,tel) values("' + req.body.username + '","' + req.body.password + '","' + req.body.email + '","' + req.body.tel + '")')
            if (bool) 
                // 添加成功-注册成功
                response(res, 1, '注册成功')
            
            response(res, 0, '注册失败')
        
    
    )
    

    给密码加密:

    const bcryptjs = require('bcryptjs')
    //处理注册逻辑
    router.post('/', async (req, res) => 
        // 获取post数据
        let result = await select('select * from user where username="' + req.body.username + '"')
        if (result.length) 
            // 如果注册过,用户名被占用
            response(res, 2, '用户名被占用')
         else 
            let password = bcryptjs.hashSync(req.body.password, 10)
            //如果没有注册过,添加到数据库
            let bool = await cud('insert user(username,password,email,tel) values("' + req.body.username + '","' + password + '","' + req.body.email + '","' + req.body.tel + '")')
            if (bool) 
                // 添加成功-注册成功
                response(res, 1, '注册成功')
            
            response(res, 0, '注册失败')
        
    
    )
    

  5. 处理登录逻辑和cookie,以及记住用户名

    //处理登录逻辑
    router.post('/', async (req, res) => 
        //查询用户名是否存在
        let result = await select('select * from user where username="' + req.body.username + '"')
        //如果存在,查询密码是否正确
        if (result.length) 

    以上是关于传统开发模式做项目:手把手教你,直击实战项目。的主要内容,如果未能解决你的问题,请参考以下文章

    传统开发模式做项目:手把手教你,直击实战项目。

    手把手教你做一个安卓点餐系统

    手把手教你做一个安卓点餐系统

    Android组件化强化实战,手把手教你搭建组件化项目架构,进阶高级开发

    物联网开发实战:手把手教你开发一款久坐提醒小助手

    手把手教你做项目多线程篇——基础知识详解