Node基础知识四——express

224 阅读5分钟

express初体验

安装

npm i expresss

体验

// 1. 导入express
const express = require('express')
​
// 2. 创建应用对象
const app = express();
​
// 3. 创建路由
app.get('/home',(req,res)=>{
    res.end('hello express')
})
​
// 4. 监听端口,启动服务
app.listen(3000,()=>{
    console.log('express 启动了 端口3000')
})
​

浏览器访问"http://127.0.0.1:3000/home",页面就会出现

hello express

1.0 路由

路由确定了应用程序如何响应客户端对特定端点的请求

路由由请求方法路径回调函数组成

express的路由格式

app.<请求方法>(路径,callback)

1.1路由的使用

// 3. 创建路由
app.get('/home',(req,res)=>{
    res.end('hello express')
})
​
// 根路由
app.get('/',(req,res)=>{
    res.end('我是首页哦')
})
// post请求
app.post('/login',(res,req)=>{
    res.end('欢迎登陆')
})
// all 代表所有请求方法 不管是post还是get 或者delete
app.all('/test',(req,res)=>{
    res.end('get post 都可以')
})
​
// 匹配所有 如果上面的没有匹配到就会走这个
app.all('*',(req,res)=>{
    res.end('404 not found')
})

1.2获取请求参数

兼容原生的方法

// 3. 创建路由
app.get('/request',(req,res)=>{
    // 原生操作
    // console.log(req.method) // 获取请求方法
    // console.log(req.url) // 获取请求url
    // console.log(req.httpVersion) // http版本
    // console.log(req.headers) // 获取请求头
​
    // express 操作
     console.log(req.path) // 获取请求路径 /request
     console.log(req.query,req.query.a) // 获取get请求参数 {a:1,b:2}
     console.log(req.ip) // 获取客户端的ip地址 ::ffff:127.0.0.1
    // 获取请求头
    console.log(String(req.get))
    // 获取具体的某一个请求头内容
    console.log(req.get('host'))
    res.end('111')
})

1.3获取路由参数

比如一个页面是

http://127.0.0.1:3000/12.html

http://127.0.0.1:3000/13.html

app.get('/:id.html',(req,res)=>{
    console.log(req.params.id)
    res.end('商品性情')
})

练习

先创建一个json文件

{
  "list": [
    {"id": 1,"name": "周几轮"},
    { "id": 2,"name": "李莉"},
    { "id": 3,"name": "张三丰" }
  ]
}
​
// 1. 导入express
const express = require('express')
// 1.5 导入json文件
const {list} = require('./src/list.json')
​
// 2. 创建应用对象
const app = express();
​
// 3. 创建路由
app.get('/:id.html',(req,res)=>{
    let id = req.params.id;
    let data = list.find((item)=>{
        if(item.id == id){
            return item
        }
    })
    res.end(`<!doctype html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport"
                  content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
            <meta http-equiv="X-UA-Compatible" content="ie=edge">
            <title>Document</title>
        </head>
        <body>
            <ul>
                <li>我是${data.name}</li>
            </ul>
        </body>
        </html>`)
})
​
// 4. 监听端口,启动服务
app.listen(3000,()=>{
    console.log('express 启动了 端口3000')
})
​

1.4 express响应设置

兼容原生的

app.get('/response',(req,res)=>{
    // 原生的响应
    // res.statusCode = 404
    // res.statusMessage = 'zl'
    // res.setHeader('xx','yy')
    // 设置响应体
    // res.write('hello express\n') // \n 换行
    // res.end('hello express')
    
    // express 的响应
    res.status(500)
    res.set('aa','bb')
    res.send('你好')
    
    // 可以链式操作
    // res.status(500).set('aa','bb').send('你好')
})

其它的响应设置

app.get('/response',(req,res)=>{
    // 其它响应
​
    // 重定向
    // res.redirect("https://www.baidu.com")
    // 下载响应
    // res.download(__dirname + '/src/list.json')
    // json 响应
    // res.json({name:'zl',age:18})
    // 响应一个文件内容
    res.sendFile(__dirname + '/src/test.html')
})

2.0 中间件

什么是中间件?

本质是一个回调函数,中间件函数可以像路由回调一样访问req和res

中间件的类型

  • 全局中间件
  • 路由中间件

2.1全局中间件

它是最先执行的,然后再执行路由

记录请求的url 和ip地址

//  导入express
const express = require('express')
// 导入fs模块
const fs = require('fs')
const path =require('path')
​
//  创建应用对象
const app = express();
​
// 声明一个中间件 记录访问的url和ip
function recordMiddleware(req,res,next){
    let {url, ip} = req
    console.log(url,ip)
    fs.appendFileSync(path.resolve(__dirname,'log.text'),`${url}   ${ip}\r\n`)
    next()
}
​
// 使用 全局中间件
app.use(recordMiddleware)
​
//  创建路由
app.get('/home',(req,res)=>{
    res.send('前台首页')
})
​
app.get('/admin',(req,res)=>{
    res.send('后台首页')
})
​
app.all('*',(req,res)=>{
    res.send('404 not found')
})
​
//  监听端口,启动服务
app.listen(3000,()=>{
    console.log('express 启动了 端口3000')
})
​

我们在页面输入路径,可以看到我们日志的文件

log.text

/home   ::ffff:127.0.0.1
/home   ::1
/admin   ::1
/favicon.ico   ::1
/admin   ::ffff:127.0.0.1

2.2路由中间件练习

需求:

针对 /admin /setting 的请求,要求url 携带 code=521参数,如果没有携带 提示 [暗号错误]

// 1. 导入express
const express = require('express')
​
// 2. 创建应用对象
const app = express();
​
// 定义路由中间件let checkCodeMiddleware = (req,res,next)=>{
    // 判断路由中是否有 code参数等于 521
    if(req.query.code == '521'){
        next()
    }else{
        res.send('暗号错误')
    }
}
​
// 3. 创建路由
app.get('/admin',checkCodeMiddleware,(req,res)=>{
     res.send('hello admin')
})
​
app.get('/setting',checkCodeMiddleware,(req,res)=>{
    res.end('hello setting')
})
​
// 4. 监听端口,启动服务
app.listen(3000,()=>{
    console.log('express 启动了 端口3000')
})
​

一般用路由中间件。校验用户的身份,用户的权限

2.3静态资源中间件

默认静态资源目录

是在public文件夹下的

新建index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>测试</h2>
</body>
</html>

新建css/app.css

*{
    margin:0;
}

node.js

// 1. 导入express
const express = require('express')
​
// 2. 创建应用对象
const app = express();
​
// 静态资源中间件
app.use(express.static(__dirname + '/public')) // 参数就是静态资源的路径// 3. 创建路由
app.get('/home',(req,res)=>{
    res.end('hello express')
})
​
// 4. 监听端口,启动服务
app.listen(3000,()=>{
    console.log('express 启动了 端口3000')
})

我们就可以这样访问了

http://127.0.0.1:3000/index.html

这个index.html 不写也可以的默认就会找到它

http://127.0.0.1:3000

css的访问

http://127.0.0.1:3000/css/app.css

如果静态资源和路由重名,谁先匹配上则谁先响应,跟代码顺序有关

3.0获取请求体里面的数据

需要一个包处理 body-parse

1.0 安装

npm i body-parse

2.0 引入

const bodyParser = require('body-parser')

3.0 获取中间件函数

// 处理 querystring 格式的请求体
let urlParser = bodyParser.urlencoded({extended:false});
​
// 处理json格式的请求体
let jsonParser = bodyParser.json()

4.0 设置路由中间件,然后使用 req.body 获取参数

app.post('/login',urlParser,(req,res)=>{
     console.log(req.body,req.params,req.query)
    res.end('获取请求体数据')
})

3.0防盗链

防止外部访问本网站资源

// 1. 导入express
const express = require('express')
​
// 2. 创建应用对象
const app = express();
​
// 3.0 静态资源中间件设置
app.use(express.static(__dirname + '/public'))
​
// 4. 监听端口,启动服务
app.listen(3000,()=>{
    console.log('express 启动了 端口3000')
})
​

此时 用http://localhost:3000/http://127.0.0.1:3000/ 都可以访问到我们的图片,

那要求只能 127.0.0.1域名的访问图片,看如下修改

// 1. 导入express
const express = require('express')
​
// 2. 创建应用对象
const app = express();
​
// 声明中间件
app.use((req,res,next)=>{
    // 检测请求头中的 referer 是否为 127.0.0.1
    // 获取 referer
    let referer = req.get('referer') // http://127.0.0.1:300
    if(referer){
        // 实例化
        let url = new URL(referer)
        // 获取 hostname
        let hostname = url.hostname
        if(hostname != '127.0.0.1'){
            res.status(404).send('404 not found')
            return
        }
    }
    next()
})
​
// 3.0 静态资源中间件设置
app.use(express.static(__dirname + '/public'))
​
// 4. 监听端口,启动服务
app.listen(3000,()=>{
    console.log('express 启动了 端口3000')
})
​

4.0路由模块化

正常情况下我们是有很多 请求我们不可能都放在一个页面,这样页面太过臃肿

//  导入express
const express = require('express')
​
//  创建应用对象
const app = express();
​
//  前台路由
app.get('/home',(req,res)=>{
    res.send('前台首页')
})
​
app.get('/search',(req,res)=>{
    res.send('前台search')
})
​
​
//  后台路由
app.get('/admin',(req,res)=>{
    res.send('后台首页')
})
​
app.get('/setting',(req,res)=>{
    res.send('后台setting')
})
​
app.all('*',(req,res)=>{
    res.send('404 not found')
})
​
//  监听端口,启动服务
app.listen(3000,()=>{
    console.log('express 启动了 端口3000')
})
​

改造

新建一个文件夹全部放路由 routes\homeRouter.js

const express = require('express')
​
// 1 创建路由对象
const router = express.Router()
​
// 2 创建理由规则
//  前台路由
router.get('/home',(req,res)=>{
    res.send('前台首页')
})
​
router.get('/search',(req,res)=>{
    res.send('前台search')
})
​
// 3 暴露对象module.exports = router
​

新建文件存放后台路由routes\adminRouter.js

const express = require('express')
​
// 1 创建路由对象
const router = express.Router()
​
// 2 创建理由规则
//  后台路由
router.get('/admin',(req,res)=>{
    res.send('后台首页')
})
​
router.get('/setting',(req,res)=>{
    res.send('后台setting')
})
​
// 3 暴露对象module.exports = router
​

修改主页面

//  导入express
const express = require('express')
​
// 引入前台路由
const homeRouter = require('./routes/homeRouter')
​
// 引入后台路由
const adminRouter = require('./routes/adminRouter')
​
//  创建应用对象
const app = express();
​
// 使用前台路由
app.use(homeRouter)
​
// 使用前台路由
app.use(adminRouter)
​
​
app.all('*',(req,res)=>{
    res.send('404 not found')
})
​
//  监听端口,启动服务
app.listen(3000,()=>{
    console.log('express 启动了 端口3000')
})
​

重点

设置路由前缀

app.use('/', homeRouter);
app.use('/users', adminRouter);

这时候访问http://127.0.0.1:3000/home没问题

但是访问admin 路径就变成了http://127.0.0.1:3000/users/admin

5.0 模板引擎

EJS 暂且不用

6.0 express-generator

可以快速生成一个应用的骨架基于express

先安装

npm install -g express-generator
​
// 2.0 查看帮助
express -h
​
// 3.0 安装模板 在eibp-node文件夹下面
 express -e eibp-node
​
// 4.0 进入文件夹eibp-node安装依赖
npm i
​
// 5.0 修改package.json里面的内容
"scripts": {
    "start": "nodemon ./bin/www"
},
// 6.0 启动项目
    npm run start

生活如果没有目标,就会变得懒散。一旦决定“今天这样做”,生活一下子就会张弛有度。

qdysh.png