01-express框架的使用

目录

一、express框架初体验

二、express路由

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

2.2 路由的使用(组成:请求方法,路径,回调函数)

2.3 获取路由参数

2.3.1 获取路由参数练习

2.4 响应设置

三、中间件

3.1 全局中间件

3.2 路由中间件

3.3 静态资源中间件

3.4 获取响应体数据

四、 防盗链

五、路由模块化

六、EJS模板引擎

6.1 ejs初体验

6.2 express中使用ejs


一、express框架初体验

1. 初始化项目 npm i

2. 下载express依赖 npm i express

3. 创建index.js文件

//导入
const express = require('express');

//创建应用对象
const app = express();

//创建路由
//首页
app.get('/', (req, res) => {
    //原生操作
    // console.log(req.method);
    // console.log(req.url)
    // console.log(req.httpVersion)
    // console.log(req.headers.host)
    
    //express操作
    res.end('home')
    console.log(req.path)
    console.log(req.query)
    //获取ip
    //console.log(req.ip)
    //获取请求头
   // console.log(req.get('host'));//127.0.0.1:5000

   //提取路由参数
   
})
app.get('/home', (req, res) => {
    res.end('hello')
})
app.post('/login', (req, res) => {
    res.end('login')
})
//匹配所有方法
app.all('/test', (req, res) => {
    res.end('test');
})
//404响应
app.all('*', (req, res) => {
    res.end('404');
})


//监听端口
app.listen(5000,()=>{
    console.log('5000端口服务启动...')
})

4. 运行index.js文件 nodemon ./index.js

二、express路由

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

2.2 路由的使用(组成:请求方法路径回调函数

2.3 获取路由参数

路由参数指的是URL路径中的参数。当详情页面很多时,一般使用占位符来替换具体值。

//导入
const express = require('express');

//创建应用对象
const app = express();

//创建路由
//首页 :code 占位符
app.get('/:code.html', (req, res) => {
    //获取URL路由参数
    let urlCode = req.params.code;
    res.setHeader('content-type','text/html;charset=utf-8')
    //express操作
    res.end('商品:'+urlCode)
   //提取路由参数
   console.log(urlCode);
})

//监听端口
app.listen(5000,()=>{
    console.log('5000端口服务启动...')
})

2.3.1 获取路由参数练习

例  根据给定的json数据展示歌手信息,路径结构 /1.html

singer.json

{
    "singers": [
        {
            "id": 1,
            "name":"歌手1"     
        },
        {
            "id": 2,
            "name":"歌手2"
        }]
}
//导入
const express = require('express');
//导入singer json文件
const {
    singers
} = require('./static/JSON/singer.json')
//console.log(singers);
//创建应用对象
const app = express();

//创建路由
//首页 :code 占位符
app.get('/:id.html', (req, res) => {
    //获取URL路由参数
    let {
        id
    } = req.params;
    

    //在数组中寻找对于id
    let result = singers.find(item => {
        //item为对象
        if (item.id === Number(id)) {
            return true;
        }
    })

    //console.log(result);
    res.setHeader('content-type', 'text/html;charset=utf-8')
    if(!result){
        res.statusCode = 404;
        res.end(`<h2>404 not found</h2>`)
    }
    res.end(`
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        
    </head>
    <body>
        <h2>${id}</h2>
        <p>${result.name}</p>
    </body>
    </html>
    `);

})

//监听端口
app.listen(5000, () => {
    console.log('5000端口服务启动...')
})

2.4 响应设置

  • res.send( ),自动添加 Content-Type: text/html; charset=utf-8
  • 可以连贯操作,链式写法。res.status().set().send();
  • 重定向响应 res.redirect( )
  • 下载响应 res.download( )
  • JSON响应 res.json( )
  • 响应文件内容 res.sendFile( )
const express = require('express');

//创建应用对象
const app = express();

//创建路由
//首页
app.get('/response', (req, res) => {
    //原生响应
    //    res.statusCode = 201;
    //    res.statusMessage ='OK!'
    //    res.setHeader('xxx','yyy')
    //    res.setHeader('ttt',['aaa','bbb']);
    //    res.write('hello!')
    //    res.end('express  response');

    // res.status(201);
    // res.set('header', ['h1', 'h2'])
    // res.send('你好 express')
    res.status(201).set('header', ['h1', 'h2']).send('你好 express');
})
app.get('/other', (req, res) => {
    //其他响应
    //重定向
    //res.redirect('https://blog.csdn.net/weixin_42152058?spm=1011.2124.3001.5343');

    //下载响应
    //res.download(__dirname + '/package.json');
    //res.status(201).set('header', ['h1', 'h2']).send('你好 express');

    //JSON响应
    // res.json({
    //     name:'json',
    //     msg:'test'
    // })

    //响应文件内容
    res.sendFile(__dirname + '/index.html') 
})

//404响应
app.all('*', (req, res) => {
    res.end('404');
})

//监听端口
app.listen(5000, () => {
    console.log('5000端口服务启动...')
})

三、中间件

  • 中间件本质一个回调函数,中间件函数可以向路由回调一样请求对象,响应对象。
  • 中间件使用函数封装公共操作,简化代码。
  • 两种类型,全局中间件和路由中间件。
  • 每个请求到达服务端之后都会执行中间件函数

3.1 全局中间件

  1. 将一些重复下代码可放到中间件函数中
  2. 声明中间件函数,res 请求报文的对象,req 响应报文的对象 ,next  内部函数:指向后续的路由回调或中间件回调。 并且一定要调用 next() , 执行后续的路由回调 
  3. 使用中间件函数

例 记录每个请求的url,ip,将信息保存 access.log中。相当于服务器的访问日志,便于查看请求的来源,可以精准的定位问题

const express = require('express');
const app = express();
const fs = require('fs');
const path = require('path')

// 声明中间件函数
function recordMiddle(req, res, next) {
    let {
        url,
        ip
    } = req;
    console.log(url, ip);
    //全局方法
    fs.appendFileSync(path.resolve(__dirname, './access.log'), `${url} ${ip} \r\n`);
    //调用next 
    next();
}
//使用中间件函数
app.use(recordMiddle);

//首页
app.get('/home', (req, res) => {
    res.status(201).send('前台');
})
app.get('/admin', (req, res) => {
    res.status(201).send('后台');
})

//404响应
app.all('*', (req, res) => {
    res.send('404');
})

//监听端口
app.listen(5000, () => {
    console.log('5000端口服务启动...')
})

3.2 路由中间件

例 针对/admin /setting 的请求,要求携带 code=2023 参数,如未携带则提示 目标错误

const express = require('express');
const app = express();
const fs = require('fs');
const path = require('path');

//中间件
let checkCodeMiddle = (req,res,next)=>{
    if(req.query.code === '2023'){
        //满足条件调用路由回调
        next();
    }else{
        res.send('目标错误')
    }
}
//首页  将中间件添加到受约束的路由规则中,放置路径后
app.get('/home', checkCodeMiddle,(req, res) => {
    res.send('前台');
});
app.get('/admin', checkCodeMiddle,(req, res) => {
    res.send('后台');
});
app.get('/setting',checkCodeMiddle,(req, res) => {
    res.send('后台设置');
});

3.3 静态资源中间件

  • 处理静态资源的中间件,通过 app.use(express.static(__dirname + '/static'));
  • index.html为默认打开资源
  • 如果静态资源与路由规则同时匹配,谁先匹配谁响应
  • 路由响应动态资源,静态资源中间件响应静态资源
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/index.css">
    <script src="./js/index.js"></script>
</head>
<body>
    <h2>i</h2>
    <p>歌手1</p>
    <img src="./img/img1.jpg" alt="" srcset="">
</body>
</html>
const express = require('express');
const app = express();
const fs = require('fs');
const path = require('path');

//防盗链
app.use((req, res, next) => {
    //检测请求头中的refer是否为127.0.0.1
    //获取referer
    let referer = req.get('referer');
    //console.log(referer);
    if (referer) {
        //实例化
        let url = new URL(referer);
        //获取 hostname
        let hostname = url.hostname;
        console.log(hostname)

        if(hostname !== '127.0.0.1'){
            res.statusCode = 404 ;
            res.send(`<h2>404</h2>`)
        }
    }

    next();
});

//静态资源中间件设置 express.static()返回一个函数
app.use(express.static(__dirname + '/static'));

//首页  将中间件添加到受约束的路由规则中,放置路径后
app.get('/', (req, res) => {
    res.send('前台');

});
app.get('/admin', (req, res) => {
    res.send('后台');
});
app.get('/setting', (req, res) => {
    res.send('后台设置');
});

//404响应
app.all('*', (req, res) => {
    res.send('404');
})

//监听端口
app.listen(5000, () => {
    console.log('5000端口服务启动...')
})

3.4 获取响应体数据

例 按照要求搭建HTTP服务

  • GET         /login         显示表单
  • POST      /admin        获取表单中的用户名和密码
  1. npm i body-parser
  2. 使用body-parser 

解析json格式的中间件

const jsonParser = bodyParser.json()

解析querystring格式的中间件

const urlencodedParser = bodyParser.urlencoded({ extended: false })

const express = require('express');
const app = express();
let bodyParser = require('body-parser')

//解析querystring格式的中间件
const urlencodedParser = bodyParser.urlencoded({ extended: false })

//首页
app.get('/login', (req, res) => {
    res.sendFile(__dirname+'/login.html')
    
});
app.post('/login',urlencodedParser,(req, res) => {
    //urlencodedParser执行完毕后,向请求对象的身上添加一个属性 body
    console.log(req.body);
    res.send('后台数据');
});

//404响应
app.all('*', (req, res) => {
    res.send('404');
})
//404响应
app.all('*', (req, res) => {
    res.send('404');
})

//监听端口
app.listen(5000, () => {
    console.log('5000端口服务启动...')
})
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="/login" method="post">
        用户名:<input type="text" name="username"><br>
        密码:<input type="password" name="password" id=""><br>
        <button>登录</button>
    </form>
</body>
</html>

四、 防盗链

 //防盗链

app.use((req, res, next) => {

    //检测请求头中的referer是否为127.0.0.1

    //获取referer

    let referer = req.get('referer');

    //console.log(referer);

    if (referer) {

        //实例化

        let url = new URL(referer);

        //获取 hostname

        let hostname = url.hostname;

        console.log(hostname)

        //主要通过判断请求头中的refefer的host是否为 当前的地址

        if(hostname !== '127.0.0.1'){

            res.statusCode = 404 ;

            res.send(`<h2>404</h2>`)

        }

    }

    next();

});

五、路由模块化

简而言之,即使将路由规则拆分到不同文件,最后在总文件require,并use,这与使用中间件函数一样。

  • index.js
const express = require('express');

const router = require('./routers/router')
const admin = require('./routers/admin')
const app = express();

app.use(router);
app.use(admin);

//404响应
app.all('*', (req, res) => {
    res.send('404');
})

//监听端口
app.listen(5000, () => {
    console.log('5000端口服务启动...')
})
  • router.js
const express = require('express');

// 创建路由对象
const router = express.Router();


//创建路由规则
router.get('/home', (req, res) => {
    res.send('前台');
});
router.get('/search', (req, res) => {
    res.send('搜索');
});

//暴露router
module.exports = router;
  • admin.js
const express = require('express');

// 创建路由对象
const router = express.Router();
//创建路由规则
router.get('/admin', (req, res) => {
    res.send('后台');
});
router.get('/setting',(req, res) => {
    res.send('后台设置');
});

//暴露router
module.exports = router;

六、EJS模板引擎

模板引擎是用户界面和业务数据的一种技术,分离html和js的

6.1 ejs初体验

  • index.html 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        h2 {
            background-color: skyblue;
        }

        img {
            width: 200px;
            height: 200px;
        }
    </style>
</head>

<body>
    <h2><%= hello%> , <%= str%></h2>
</body>

</html>
  •  list.html  列表渲染

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>批量渲染</h2>
    <ul>
    <% arry.forEach(item => { %>
    <li><%= item %></li>
    <% }) %>
</ul>
</body>
</html>
  •  check.html 条件渲染

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <header>
        <% if(isLogin){ %>
        <span>welcome</span>
        <% }else{ %>
        <button>登录</button> <button>注册</button>
        <% } %>
    </header>

</body>

</html>
  • test.js

const express = require('express');
const app = express();
const ejs = require('ejs')
const fs = require('fs');
const path = require('path');
app.get('/', (req, res) => {
    let hello = 'hello';
    let str = 'ejs'
    let data = fs.readFileSync('./index.html').toString();
    //使用ejs渲染
    let result = ejs.render(data, {
        str: str,
        hello
    })
    //console.log(result);
    res.send(result);
});

//列表渲染
app.get('/list', (req, res) => {
     const arry = ['aa', 123, 201, 'test'];
     //1.原生js
    /*
    let ul = '<ul>';
    arry.forEach(item => {
        ul += `<li>${item}</li>`
    })
    ul += '</ul>'
    console.log(ul)
    */

    //2.ejs实现
    let data2 = fs.readFileSync('./list.html').toString();
    let ul = ejs.render(data2,{arry})
    console.log(ul);
    res.send(ul);
})
//条件渲染
/**通过isLogin决定最终的输出内容
 * true <span>welcome</span>
 * false <button>登录</button>  <button>注册</button>
 */
app.get('/check', (req, res) => {
    let isLogin =true;
    let data3 = fs.readFileSync('./check.html').toString();
    let result = ejs.render(data3,{isLogin:isLogin})
    res.send(result);
})
//404响应
app.all('*', (req, res) => {
    res.send('404');
})

//监听端口
app.listen(5000, () => {
    console.log('5000端口服务启动...')
})

6.2 express中使用ejs

  1. 先设置模板引擎,如ejs、pug 、twingdeng 
  2. 设置模板文件存放位置,且路径转成绝对路径
  3. 调用 res.render(模板的文件名,数据),响应文件内容
  • home.ejs
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>ejs测试   <%= str %></h2>
</body>
</html>
  • index.js
const express = require('express');
const path = require('path')
const app = express();

//设置模板引擎 pug  twing
app.set('view engine','ejs');
//设置模板文件存放位置,存放路径转成绝对路径  具有模板语法内容的文件
app.set('views',path.resolve(__dirname,'./views'))


app.get('/home', (req, res) => {
    let str = '模板文件';
    //render响应  res.render(模板的文件名,数据)
    res.render('home',{str});
})

//监听端口
app.listen(5000, () => {
    console.log('5000端口服务启动...')
})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

才不吃胡萝卜嘞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值