express框架

10 篇文章 0 订阅
4 篇文章 0 订阅

一、express介绍

express是一个基于Node.js平台的极简、灵活的WEB应用开发框架,官方网址https://www.expressjs.com.cn/

简单来说,express是一个封装好的工具包,封装了很多功能,便于我们开发WEB应用(HTTP服务)

二、express使用

2.1 express下载

express本身是一个npm包,所以可以通过npm安装

npm i express

2.2 express初体验

// 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('服务已启动...3000端口正在监听');
})

三、express路由

3.1 什么是路由

**官方定义:**路由确定了应用程序如何相应客户端对特定端点的请求

3.2 路由的使用

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

express中提供了一系列的方法,可以和你方便的使用路由

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

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

// 3.创建路由
//get方法请求
app.get('/home',(req,res)=>{
    res.end('hello express');
});
//首页路由
app.get('/',(req,res)=>{
    res.end('我是首页');
});
//post方法请求
app.post('/login',(req,res)=>{
    res.end("login login");
});
//所有方法的请求
app.all('/test',(req,res)=>{
    res.end('test test');
});
// 404响应
app.all('*',(req,res)=>{
    res.end('404 Not Found');
});
// 4.监听端口,启动服务
app.listen(3000,()=>{
    console.log('服务已启动...3000端口正在监听');
});

3.3 获取请求参数

express框架封装了一些API来方便获取请求报文中的数据没并且兼容原生HTTP模块的获取方式

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

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

// 创建路由
app.get('/request',(req,res)=>{
//原生操作
// 1.获取报文的方式与原生HTTP获取方式是兼容的
    console.log(req.method);
    console.log(req.url);
    console.log(req.httpVersion);
    console.log(req.headers);

// 2.express独有的获取报文的方式
    console.log(req.path);
    //获取查询字符串
    console.log(req.query);//相对重要
    //获取ip
    console.log(req.ip);
    // //获取指定的请求头
    // console.log(req.get('host'));
    res.end('hello express');
    });

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

3.4 获取路由参数

路由参数指的是URL路径中的参数(数据)

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

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

// 创建路由
app.get('/:id.html',(req,res)=>{
    res.setHeader('content-type','text/html;charset=utf-8');
    res.end('商品详情,商品id为'+req.params.id)
});

// 监听端口,启动服务
app.listen(3000,()=>{
    console.log('服务已启动...3000端口正在监听');
});

3.5 歌手案例

{
    "singers": [
        {
            "singer_name": "周杰伦",
            "singer_pic": "https://p2.ifengimg.com/2019_20/93F1AA4B254456CF1F06C237E5B95C59E68126B1_w2300_h1724.jpg",
            "other_name": "Jay Chou",
            "singer_id": 4558,
            "id": 1
        },
        {
            "singer_name": "林俊杰",
            "singer_pic": "http://y.gtimg.cn/music/photo_new/T001R150x150M000001BLpXF2DyJe2.webp",
            "other_name": "Lin",
            "singer id": 4286,
            "id": 2
        },
        {
            "singer_name": "G.E.M.邓紫棋",
            "singer_pic": "https://tse4-mm.cn.bing.net/th/id/OIP-C.1m1ACN9T60PedYwYta0WGAHaHt?w=186&h=194&c=7&r=0&o=5&dpr=2&pid=1.7",
            "other_name": "Gloria Tang",
            "singer_id": 13948,
            "id": 3
        }
    ]
}
// 导入express
const express=require('express');
//导入JSON文件
const {singers}=require('./singers.json');
console.log(singers);
// 创建应用对象
const app=express();

// 创建路由
app.get('/singer/:id.html',(req,res)=>{
    //获取路由参数
    let {id}=req.params;
    //在数组寻找对应id的数据
    let result=singers.find(item=>{
        if(item.id===Number(id)){
            return true;
        }
    });
    if(!result){
        res.statusCode=404;
        res.end(`<h1>404 Not Found</h1>`);
        return;
    }
    console.log(result);
    res.end(`
    <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
   <h3>${result.singer_name}</h3>
   <img src='${result.singer_pic}'/ width=300px>
</body>
</html>`)
});

// 监听端口,启动服务
app.listen(3000,()=>{
    console.log('服务已启动...3000端口正在监听');
});

四、express 响应设置

express框架封装了一些API来方便给客户端响应数据,并且兼容原生HTTP模块的获取方式

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

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

// 创建路由
app.get('/response',(req,res)=>{
    //原生响应
    // res.statusCode=404;
    // res.statusMessage='love';
    // res.setHeader('xxx','yyy');
    // res.write('hello express')
    // res.end('rsponse')

    //express响应
    // res.status(500);
    // res.set('aaa','bbb');
    // res.send('你好 Express');//不用设置字符集,自动设置了

    //连贯操作
    res.status(500).set('aaa','sdf').send("这些都是OK的")
});

// 监听端口,启动服务
app.listen(3000,()=>{
    console.log('服务已启动...3000端口正在监听');
});
// 导入express
const express=require('express');

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

// 创建路由
app.get('/other',(req,res)=>{
    //跳转响应(重定向)
    // res.redirect('http://atguigu.com');
    //下载响应
    // res.download(__dirname+'/package.json');//单独的语句
    //json响应
    // res.json({
    //     name:'尚硅谷',
    //     slogon:'让天下没有难学的技术'
    // });
    // res.send('你好 Express');//不用设置字符集,自动设置了
    //响应文件内容
    res.sendFile(__dirname+'/test.html')

});

// 监听端口,启动服务
app.listen(3000,()=>{
    console.log('服务已启动...3000端口正在监听');
});

五、express中间件

5.1 什么是中间件

中间件(Middleware)本质是一个回调函数

中间件函数可以像路由回调一样访问请求对象(request),响应对象(response)

5.2 中间件的作用

中间件的作用就是使用函数封装公共操作,简化代码

5.3 中间件的类型

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

5.3.1 定义全局中间件

每一个请求到达服务端之后都会执行全局中间件函数

/**
 * 记录每一个请求的URL与Ip地址(服务器的访问日志)
 */

// 导入express
const express=require('express');
const fs=require('fs');
const path=require('path');
// 创建应用对象
const app=express();

//声明中间件函数
function recordMiddleware(req,res,next){
 //获取url和Ip
 let {url,ip}=req;
 //将信息保存在文件中 access.log
 fs.appendFileSync(path.resolve(__dirname,'./access.log'), `${url} ${ip}\r\n`);
 //调用next
 next();
}
//使用中间件函数
app.use(recordMiddleware);

// 创建路由
app.get('/home',(req,res)=>{
    res.send('前台首页');
});

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

app.all('*',(req,res)=>{
    res.send('<h1>404 Not Found</h1>');
});

// 监听端口,启动服务
app.listen(3000,()=>{
    console.log('服务已启动...3000端口正在监听');
});

5.3.2 路由中间件实践

/**
 * 针对 /admin /setting的请求,要求携带code=521的参数,如未携带提示 暗号错误
 */

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

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

// 创建路由
app.get('/home',(req,res)=>{
    res.send('前台首页');
});

//声明中间件
let checkCodeMiddleware=(req,res,next)=>{
       //判断URL中是否code参数等于521
       if(req.query.code==='521'){
        next();
    }else{
        res.send("暗号错误");
    }
}

app.get('/admin',checkCodeMiddleware,(req,res)=>{
    res.send("后台首页");
});

app.get('/setting',checkCodeMiddleware,(req,res)=>{
    res.send("设置页面");
});

app.all('*',(req,res)=>{
    res.send('<h1>404 Not Found</h1>');
});

// 监听端口,启动服务
app.listen(3000,()=>{
    console.log('服务已启动...3000端口正在监听');
});

5.4 静态资源中间件

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

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

//静态资源中间件设置,将当前文件夹下的public目录作为网站的根目录
app.use(express.static(__dirname+'/public'));//当然这个目录都是一些静态资源
// 创建路由
app.get('/index.html',(req,res)=>{
    res.end('首页');
});

// 监听端口,启动服务
app.listen(3000,()=>{
    console.log('服务已启动...3000端口正在监听');
});

注意事项:

  1. index.html 文件为默认打开的资源
  2. 如果静态资源与路由规则同时匹配,谁先匹配谁就响应
  3. 路由响应动态资源,静态资源中间件响应静态资源

5.5 获取请求体数据 body-parse

express可以使用body-parse包处理请求体

第一步:安装

npm i body-parse

第二步:导入 body-parse包

const bodyParse=require('body-parse');

第三步:获取中间件函数

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

第四步:设置路由中间件,然后使用request.body来获取请求体数据

/**
 * 按照要求搭建HTTP服务
 * 
 * get  /login   显示表单网页
 * post /login   获取表单中的用户名和用户数据
 */ 
// 导入 express
const express=require('express');
const bodyParser=require('body-parser');

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

//解析JSON格式的请求体的中间件
const jsonParser=bodyParser.json()

//解析querystring格式请求体的中间件
const urlencodeParser=bodyParser.urlencoded({extended:false});

//创建路由规则
app.get('/login',(req,res)=>{
    // res.send('表单页面')
    //响应html 文件内容
    res.sendFile(__dirname+'/11_form.html');
});
// post 规则
app.post('/login',urlencodeParser,(req,res)=>{
    //获取用户名和密码
    console.log(req.body);
    res.send('获取用户数据');
});

// 启动服务
app.listen(3000,()=>{
    console.log('3000 server is running...');
});

当urlencodeParser中间件执行完毕后会在req上加一个属性body

5.6 图片防盗链

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

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

//声明中间件
app.use((req,res,next)=>{
    //检测请求头中的referer是否为127.0.0.1
    //和获取referer
    let referer=req.get('referer');
    if(referer){
        //实例化
        let url =new URL(referer);
        //获取hostname
        let hostname=url.hostname;
        //判断
        if(hostname!=='127.0.0.1'){
            //响应404
            res.status(404).send('<h1>404 Not Found</h1>');
            return;
        }
    }
    next();
});

//静态资源中间件设置
app.use(express.static(__dirname+'/public'));//相当于根目录root


// 监听端口,启动服务
app.listen(3000,()=>{
    console.log('服务已启动...3000端口正在监听');
});

六、 路由模块化

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

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

// 首页
router.get('/home',(req,res)=>{
    res.send('前台首页');
});
// 搜索
router.get('/search',(req,res)=>{
    res.send('搜索页面');
});

//对外暴露模块
module.exports=router;
//1.导入express
const express=require('express');

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

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

//对外暴露模块
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('<h1>404 Not Found</h1>');
});

// 监听端口,启动服务
app.listen(3000,()=>{
    console.log('服务已启动...3000端口正在监听');
});

七、EJS模板引擎

7.1 什么是模板引擎

分离用户界面和业务数据的一种技术(分离HTML与JS的技术,降低耦合)

7.2 什么是EJS

EJS是一种高效的JavaScript的模板引擎

官网:https://ejs.co/

中文站:https://ejs.bootcss.com

7.3 EJS初体验

下载安装EJS

npm i ejs 
//导入EJS
const ejs=require('ejs');
const fs=require('fs');

//字符串
let china ='中国';
let weather='今天天气不错~'


//声明变量
let str=fs.readFileSync('./01_html.html').toString();

//声明EJs渲染
let result=ejs.render(str,{china,weather});

console.log(result);

7.4 列表渲染

const ejs=require('ejs');

const xiyou=['唐僧','孙悟空','猪八戒','沙和尚']

// //原生js
// let str='<ul>';
// xiyou.forEach(item=>{
//     str+=`<li>${item}</li>`;
// });

//EJS 实现

const fs=require('fs');
let html=fs.readFileSync('./02_西游.html').toString();
let result= ejs.render(html,{xiyou:xiyou});

console.log(result);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>西游四人组</h2>
    <ul>
        <% xiyou.forEach(item => {  %>
            <li><%= item %></li>
        <% }) %>
    </ul>
</body>
</html>

注意:一但模板拼接写错,就会出现SyntaxError: Unexpected token ';' while compiling ejs的错误

7.5 条件渲染

<% if(isLogin){ %>
        <span>欢迎回来</span>
        <%}else{%>
    <button>登录</button> <button>注册</button>
    <% }%>

7.6 express中使用EJS

const express=require('express');
const path=require('path');
//导入express 模块
const app=express();
// 1.设置模板引擎
app.set('view engine','ejs');//pug twing
// 2.设置模版文件存放位置  模板文件:具有模板语法内容的文件
app.set('views',path.resolve(__dirname,'./views'));

// 创建路由
app.get('/home',(req,res)=>{
// 3.render响应
// res.render('模板的文件名','数据');
// 声明变量
let title='捉襟见肘记账本'
res.render('home',{title});
// 4.创建模板文件
});

// 监听端口,启动服务
app.listen(3000,()=>{
    console.log('服务已启动,3000端口正在监听中...');
});
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2><%= title %></h2>
    <h2>哈喽</h2>
</body>
</html>

7.7 Express应用程序生成器

通过应用程序生成器工具express-generator可以快速创建一个应用的骨架。

安装:

npm install -g express-generator

添加ejs模版引擎的支持

express -e 文件夹名称

7.8 文件上传

具体看代码15-generator文件夹中的图片上传

问题1:Error: Cannot find module ‘cookie-parser’

请添加图片描述

问题产生的原因是:express4里要单独安装cookie-parser和express-session

解决办法:

插入代码块:

npm install express-session --save

npm install cookie-parser --save

问题2:formidable not a function

获取包的时候加上{},如下:

const {formidable}=require('formidable');

扩展:lowdb

安装指定版本的lowdb

npm i lowdb@1.0.0

轻量级本地JSON数据库

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值