传统开发模式做项目:手把手教你,直击实战项目。
Posted 贪吃ღ大魔王
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了传统开发模式做项目:手把手教你,直击实战项目。相关的知识,希望对你有一定的参考价值。
传统开发模式做项目
使用模板引擎,在静态页面中书写js逻辑,所以项目中需要使用模板引擎
步骤:
-
将做的项目src放到project中
在project中 进行项目初始化
npm init -y
-
下载依赖的模块:
需要用到的
npm i express art-template express-art-template cookie-parser body-parser bcryptjs mysql svg-captcha
-
就在src所在文件夹中新建app.js用来创建服务器
// 创建服务器 const express = require('express') const app = express() app.get('/',(req,res)=>{ res.send('服务器搭建成功') }) app.listen(3000)
-
在package.json文件中配置启动项目的命令:
"scripts": { "test": "echo \\"Error: no test specified\\" && exit 1", "start":"nodemon app.js" },
-
启动服务器
npm start
再打开浏览器测试:http://localhost:3000
服务器就搭建成功了…
-
静态资源托管:
app.use('/src', express.static('src'))
打开浏览器:就可以访问项目的index.html
-
设置模板引擎,处理 / 路由请求的时候,将首页的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'))
这样的话,当我们在浏览器中访问静态资源就能出现了
-
-
同样的道理,其他html文件,也需要通过模板引擎渲染显示,所以我们需要将其他html文件都剪切到template文件夹下
-
模块化开发 - 将所有请求的处理交给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)
-
将所有请求都交给responseRouter去处理
-
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
-
每个模块去处理一个请求
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)
都可以正常访问了
-
添加异常处理中间件:为了更好的用户体验
// 在最下面添加异常处理中间件 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>
-
添加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>
-
跟上面响应首页的时候一样,将别的页面也渲染出来,在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路由
-
处理其他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, '注册失败') } })
-
处理登录逻辑和cookie,以及记住用户名
//处理登录逻辑 router.post('/', async (req, res) => { //查询用户名是否存在 let result = await select('select * from user where username="' + req.body.username + '"') //如果存在,查询密码是否正确 传统开发模式做项目:手把手教你,直击实战项目。