1.1 nodemon的作用:能够实时监听当前项目中,文件的变化;只要监听到了文件的变化,则 nodemon 工具,会自动重新启动 web 服务器,从而使最新的代码生效;免去了程序员手动重启服务器的困扰;
1.2 如何安装:运行 npm i nodemon -g 全局安装即可;
1.3 如何使用:
nodemon .\01-express中使用art-template.js
定义(什么是Express):一个快速的网站开发框架,封装了原生的http模块,用起来更方便;API更人性化
npm i express -S
// 导入 expree第三方模块
const express = require('express')
// 创建服务器的实例
const app = express()
// 监听客户端请求
app.get('/',(req,res) => {
// res.end('你好!') //end()为http模块的方法,express也可以用 乱码问题
res.send("你好!") //express方法 没有乱码问题
})
// 启动服务器
app.listen(3000,() => {
console.log('server running at http://127.0.0.1:3000')
})
app.get('/',(req,res) => {
res.send('Ok') //普通字符串
res.send({name:'cc',age:16}) //对象 {"name":"cc","age":16} json格式
res.send(['吃饭','睡觉','打豆豆']) //数组 ["吃饭","睡觉","打豆豆"]
res.send(new Buffer('123')) //二进制 下载效果 不常用
})
app.get('/',(req,res) => {
// 一个参数:这个参数必须是绝对路径
// res.sendFile(path.join(__dirname,'./public/index.html'))
// 两个参数: 第一个实参可传相对路径 第二个必须是绝对路径
res.sendFile('./public/index.html',{root:__dirname})
})
app.get('/movie',(req,res) => {
res.sendFile('./public/movie.html',{root:__dirname})
})
app.get('/about',(req,res) => {
res.sendFile('./public/about.html',{root:__dirname})
})
app.use(express.static('./public'))
// app.use()专门用来注册中间件
// express.static()把指定的目录托管为静态资源目录,这样指定目录下的所有文件都可以直接被浏览器访问,是express的内置中间件;
app.use('/page',express.static('./public'))
// /page:指定要挂载的虚拟路径
npm i ejs -S
// 使用 app.set('view engine',引擎模板的名称)
app.set('view engine','ejs')
//设置模板页面的默认存放路径 app.set('views','模板页面的具体存放路径')
app.set('views','./ejs_pages') //默认存放路径
app.get('/',(req,res) => {
//若想调用res.render,必须先配置引擎模板
res.render('index.ejs',{name:'cc',age:16,hobby:['吃饭','睡觉','打豆豆']})
})
cnpm i art-template express-art-template -S
const artTemplate = require('express-art-template')
// 注意: 安装两个包 art-template express-art-template 安装多个包用空格隔开
// 1.使用app.engine方法自定义模板引擎(模板引擎的名字,artTemplate)
// 这个位置配置的模板引擎的名字将会是模板文件的后缀名称
app.engine('html',artTemplate)
// 2 使用app.set('view engine','指定模板引擎名称')来配置项目中用到的模板引擎
app.set('view engine','html')
// 3 配置模板页面的存放路径 配置模板引擎的根目录
app.set('views','./art-pages')
app.get('/',(req,res) => {
res.render('index.html',{name:'cc',age:16,hobby:['吃饭','睡觉','打豆豆']})
})
什么是路由:路由就是对应关系;
什么叫做后端路由:前端请求的URL地址,都要对应一个后端的处理函数,那么 这种URL地址到 处理函数之间的对应关系,就叫做后端路由;
定义路由模块
// 1. 封装单独的 router.js 路由模块文件
const express = require('express')
// 创建路由对象
const router = express.Router()
router.get('/', (req, res)=>{})
router.get('/movie', (req, res)=>{})
router.get('/about', (req, res)=>{})
// 导出路由对象
module.exports = router
// 导入自己的路由模块
const router = require('./router.js')
// 使用 app.use() 来注册路由
app.use(router)
定义:中间件就是一个处理函数;只不过这个函数比较特殊,包含了三个参数,分别是 req,res,next
注意:中间件方法中的三个参数:
- req:请求对象;
- res:响应对象;
- next:next()可以被调用,表示调用下一个中间件方法;
- 应用级别的中间件: 挂载到 app 上的中间件 app.get(‘URL地址’, (req, res, next)=> {});
- 路由级别的中间件: 挂载到 router 对象上的中间件 router.get(‘url地址’, (req, res, next)=>{})
- 错误级别的中间件: 回调函数中,有四个参数 app.use((err, req, res, next)=>{})
- 唯一内置的中间件: express.static()
- 第三方中间件: 非express框架提供的,需要程序员手动安装才能使用的中间件;body-parser 解析post 表单数据
const querystring = require('querystring');
// 定义应用级别的中间件
app.use((req,res,next) => {
let dataStr = ''
// 只要客户端向服务器提交了表单,都会触发req的data事件
// 在data事件中,可以获取客户端每次提交过来的不完整的数据
req.on('data',chunk => {
dataStr += chunk
})
// 只要req出发了end事件,就表示表单数据提交完毕
req.on('end',() => {
// console.log(dataStr) //username=cc&userage=12
//想要把 username=ls&password=123 字符串,
//解析为 { username: 'ls', password: 123 }
// querystring.parse() 方法将 URL 查询字符串 dataStr 解析为键值对的集合。
const obj = querystring.parse(dataStr)
req.body = obj
// 注意:在中间件中,最后一定要合理调用next(),否则服务器无法结束这次响应
next()
})
})
// get请求
app.get('/',(req,res) => {
res.sendFile('./11-中间件index.html',{root:__dirname})
})
// post请求
app.post('/postdata',(req,res) => {
res.send(req.body) //{"username":"cc","userage":"123"}
})
npm i mysq
// 1.导入mysql模块
const mysql = require('mysql')
// 2.创建mysql的连接对象
const conn = mysql.createConnection({
host:'localhost',
user:'root',
password:'root',
database:'express-mysql'
})
// 查询conn.query('sql语句',回调函数)
const sql ='SELECT * FROM `user` '
conn.query(sql,(err,result) => {
if(err) return console.log('获取数据失败'+err.message)
console.log(result)
//[ RowDataPacket { id: 1, name: 'cc', age: 16, gender: 'girl' } ]
})
const user = {name:'zz',age:22,gender:'boy'}
const sql = "INSERT INTO `user` SET ?"
conn.query(sql,user,(err,result) => {
if(err) return console.log('插入数据失败'+err.message)
console.log(result)
// OkPacket {
// fieldCount: 0,
// affectedRows: 1,
// insertId: 6,
// serverStatus: 2,
// warningCount: 0,
// message: '',
// protocol41: true,
// changedRows: 0
// }
})
const user ={id:6,name:'zz',age:18}
const sql = 'UPDATE `user` SET ? WHERE id = ?'
//若sql语句中包含多个?占位符,第二个实参必须传递一个数组,并一一对应
conn.query(sql,[user,user.id],(err,result) => {
if(err) return console.log("修改数据失败")
console.log(result)
// OkPacket {
// fieldCount: 0,
// affectedRows: 1,
// insertId: 0,
// serverStatus: 2,
// warningCount: 0,
// message: '(Rows matched: 1 Changed: 1 Warnings: 0',
// protocol41: true,
// changedRows: 1
// }
})
const sql = 'DELETE FROM `user` WHERE id=?'
conn.query(sql, 1, (err, result) => {
if (err) return console.log('删除失败!' + err.message)
console.log(result)
// OkPacket {
// fieldCount: 0,
// affectedRows: 1,
// insertId: 0,
// serverStatus: 2,
// warningCount: 0,
// message: '',
// protocol41: true,
// changedRows: 0
// }
})