express框架学习笔记

express简介

express是一个基于Node.js平台的极简的、灵活的WEB应用开发框架。express是一个封装好的工具包,封装了很多功能,便于我们开发WEB应用(HTTP服务)

express使用

新建express文件夹新建文件test01.js,代码如下

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

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

// 创建路由
app.get('./home', (req, res) => {
    res.end('hello');
});

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

npm初始化,然后新建express-learn,接着运行node test01.js,报错
在这里插入图片描述

在目录下安装express并将其保存到依赖列表

npm install express --save

运行成功。
只有请求方法是get请求路径是/home的时候回调函数才会实现,请求的url路径是/,所以响应404
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

express路由

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

express路由的使用

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

app.<method>(path.callback)

GET请求

app.get('/', (req, res) => {
    res.end('home');
});

POST请求

app.post('/login', (req, res) => {
    res.end('i m login')
})

使用表单发送post请求

   <form method="post" action="http://127.0.0.1:3000">
        <button>登录</button>
    </form>

其他的一些具体案例

//post
app.post('/login', (req, res) => {
    res.end('i m login')
});
// 匹配所有的方法
app.all('/test', (req, res) => {
    res.end('test')
})
// 404响应
app.all('*', (req, res) => {
    res.end('404 not found')
})

在这里插入图片描述
在这里插入图片描述

注意路径名不要添加点,不然可能会出现错误

获取报文数据

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

核心代码

 // 获取查询字符串
    console.log(req.query);
    // 获取指定的请求头
    console.log(req.get('host'));

    res.send('请求报文的获取');

在这里插入图片描述

获取路由参数

商城中的商品的id不同,对应的商品详情页面也不相同,所以使用下面的代码匹配

app.get('/:id.html', (req, res) => {
    // 获取URL路由参数
    console.log(req.params.id);
    res.getHeader('content-type', 'text/html;charset=utf-8');
    res.end('商品详情');
});

两个id名称保持一致。
在这里插入图片描述
在这里插入图片描述

express响应设置

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

app.get("/response", (req, res) => {
    // express中设置响应的方式兼容HTTP模块的方式
    res.statusCode = 404;
    res.statusMessage = 'xxx';
    res.setHeader('abc', 'xyz');
    res.write('响应体');
    res.end('xxx');
    })

express的响应方法

    res.status(500);
    res.set('xxx', 'yyy');
    res.send('中文响应不乱码');
    // 连贯操作
    res.status(404).set('xxx', 'yyy').send('你好朋友')
    // 3其他响应
    res.redirect('http://xxx.com')//重定向
    res.download('./package.json');//下载响应
    res.json();//响应json
    res.sendFile(__dirname + '/home.html')//响应文件内容

json响应可以是下面这样

  res.json({
        name: '隐藏用户',
        rank: 'top1'
    });

将html文件内容响应给网页可以使用

res.sendFile(_dirname+'/test.html')

或者是path.resolve()

中间件

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

中间件的作用

使用函数封装公共操作,简化代码

中间件的类型

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

定义全局中间件

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

执行下面的函数

app.get('/home', (req, res) => {
    // 获取url和ip
    let { url, ip } = req;
    // 将信息保存在文件中access.log
    fs.appendFileSync(path.resolve(__dirname, './access.log'), `${url}  ${ip}\r\n`);///home 127.0.0.1
    res.send('前台首页');
});

推荐插件Template String Converter,可以在${}输入字符串时候自动生成反引号
在这里插入图片描述
在这里插入图片描述

每个路由规则都要写app.get里面的两行代码,先上车后检查的类似操作后续维护不便,这是我们可以考虑中间件操作

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

req是接收请求报文的对象,res是接收响应报文的对象,next是内部函数,执行后指向路由回调或者中间件回调.

路由中间件实践

需求:针对/admin /setting的请求,要求URL携带code=521的参数,如未携带提示【暗号错误】;
声明中间件函数,并设置在受约束的路由规则当中

// 声明中间件
let checkCodeMiddleware = (req, res, next) => {
    // 判断URL中的是否code参数等于521
    if (req.query.code === '521') {
        // res.send('登录页面');不能每个请求都响应登录页面,这样其他页面都失效了
        next();//满足条件就可以执行后续代码
    } else {
        res.send('暗号错误');
    }
}
app.get('/admin', checkCodeMiddleware, (req, res) => {
    res.send('后台首页');
});
// 后台设置
app.get('/setting', checkCodeMiddleware, (req, res) => {
    res.send('设置页面');
});

在这里插入图片描述

先执行中间件里面的代码,执行next,执行路由回调。路由中间件就可以封装代码。项目中一般使用中间件校验用户身份或者权限。

静态资源中间件

静态资源中间件的设置

// 静态资源中间件设置
app.use(express.static(__dirname + '/public'));

express.static()返回结果是一个中间件函数,参数是静态资源文件夹的路径,服务端到文件夹寻找对应文件,读取文件,响应内容。
在这里插入图片描述

注意事项

  1. express.html文件为默认打开的资源
    在这里插入图片描述

  2. 如果静态资源和路由规则同时匹配,谁先匹配谁就响应

   app.use(express.static(__dirname + '/public'));


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

两个同时匹配上,先匹配前面的就先响应前面的
3. 路由响应动态资源,静态资源中间件响应静态资源

获取请求体数据

核心步骤

  1. 安装
  2. 导入包
  3. 获取中间件函数
  4. 设置路由中间件,然后使用request.body来获取请求体数据

需求

按照要求搭建HTTP服务
get /login 显示表单网页
post /login 获取表单中的用户名和密码

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

const app = express();

app.get('/login', (req, res) => {
    res.send('表单页面')
});

app.post('/login', (req, res) => {
    res.send('获取用户的数据')
});
app.listen(3000, () => {
    console.log('服务已启动')
})

在这里插入图片描述

post请求需要用表单来发起,新建form表单,修改路由规则里面响应html内容

app.get('/login', (req, res) => {
    // res.send('表单页面')
    res.sendFile(__dirname + '/_form.html')
});

在这里插入图片描述

因为响应的表单数据是querystring格式的,所以使用第二个

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

// 解析querystrinng格式请求体的中间件
var urlencodedParser = bodyParser.urlencoded({ extended: false })

app.post('/login', urlencodedParser, (req, res) => {
    console.log(req.body);
    res.send('获取用户的数据');
});

防盗链

在网页中选择图片,右键复制图片链接,将其引入html的img里面,打开html,有的显示有的不显示,不显示的就是开启了防盗链。防止外部网站盗用本网站资源。

设置一张图片可以127.0.0.1访问禁止localhost访问

// 声明中间件
app.use((req, res, next) => {
    // 检测请求头中的referer是否为127.0.0.1
    // 获取referer
    let referer = req.get('referer');
    if (referer) {//有refer进入函数内,没有直接下一步
        // 实例化
        let url = new URL(referer);
        // 获取hostname
        let hostname = url.hostname;
        console.log(hostname)
        if (hostname !== '127.0.0.1') {
            res.status(404).send('<h1>404</h1>')
        }
    }
    console.log(referer);
    next();
})
app.use(express.static(__dirname + '/public'));

在这里插入图片描述
在这里插入图片描述

路由模块化

将路由的代码进行模块化处理,将13文件中的前台的路由移动到homeRouter.js中,然后在13文件中导入homeRouter,设置app.use(homeRouter)

主要步骤

  1. 导入express
  2. 创建路由对象
  3. 创建路由规则
  4. 暴露router
    在文件13中引入
const homeRouter = require('./homeRouter')
app.use(homeRouter);

homeRouter的代码

const express = require('express');
const router = express.Router();
router.get('/home', (req, res) => {
    res.send('前台首页');
});
router.get('/search', (req, res) => {
    res.send('内容搜索');
});
module.exports = router;

在这里插入图片描述
在这里插入图片描述

后台也可以路由模块化处理。

EJS模板引擎

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

EJS是一个高效的JavaScript的模板引擎。

使用方法

下载安装

npm i ejs --save

使用步骤

  1. 下载安装
  2. 引入ejs
  3. 定义数据
  4. ejs解析模板返回结构

ejs列表渲染

const ejs = require('ejs');
let person = ['张三', '李四', '二狗'];
// js
let str = '<ul>';
person.forEach(item => {
    str += `<li>${item}</li>`;
})

str += '</ul>';
console.log(str);
// ejs
let result = ejs.render(`<ul>
<% person.forEach(item =>{ %>
    <li><%= item %></li>
    <% }) %>
    </ul>`, { person: person });

console.log(result)

在这里插入图片描述
在这里插入图片描述

<ul>
        <% person.forEach(item=>{ %>
            <li>
                <%= item %>
            </li>
            <% }) %>
    </ul>

写入html文件,然后编写EJS

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

console.log(result)

在这里插入图片描述

EJS条件渲染

需求:通过isLogin决定最终的输出内容
true 输出 欢迎回来
false输出登录 注册

// 变量
let isLogin = true;

// 原生js
if (isLogin) {
    console.log('<span>欢迎回来</span>')
} else {
    console.log('<button>登录</button> <button>注册</button>')
}

// ejs
let result = ejs.render(`
    <% if(isLogin){%>
<span>欢迎回来</span>
   <% }else{%>
   <button>登录</button> <button>注册</button>
    <% }%>`,
    { isLogin: isLogin }
);

左边的isLogin和if里面的保持一致,,右边的和变量名称保持一致.
进一步操作,将ejs代码剪切到html中

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

在js文件中读取html文件

let html=fs.readFileSync('./_home.html').toString();

运行报错,原因忘记引入fs模块和ejs模块,引入后运行截图
在这里插入图片描述

express中使用ejs

模板文件:具有模板语法的文件,比如之前具有模板语法的html文件

res.render(‘模板的文件名’,‘数据’)

// 导入express
const express = require('express');
// 创建应用对象
const app = express();
//1. 设置模板引擎
app.set('view engine', 'ejs')
// 2.设置模板文件存放位置
app.set('views', path.resolve(__dirname, './views'));


// 创建路由
app.get('/home', (req, res) => {
    //    3.render响应
    //声明变量
    let title = '隐藏用户top1';
    res.render('home', { title });
    // 4.模板文件

});

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

express-generator

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

安装使用

npm install -g express-generator

安装完成后使用express -h可以查看帮助
在这里插入图片描述

将代码下载到一个新的文件夹下面

express -e  文件夹名称

新建的文件夹为generator,在generator里面安装依赖npm i
之后可以使用npm start运行项目
404的两种写法

 app.use(function(req, res, next) {
  next(createError(404));
});
app.all('*', (req, res) => {
    res.end('404 not found')
})

查看文件上传报文

multipart/form-data是文件上传的必需属性。

在这里插入图片描述

npm start运行之后报错,
在这里插入图片描述

原因在于index.js里面没有写post
在这里插入图片描述

机械的敲代码,看走眼了。。。

修改之后页面功能全部正常

处理文件上传

首先安装一个包formidable

npm i formidable

引入formidable然后写入下面的代码

router.post('/portrait', (req, res) => {
  // 创建form对象
  const form = formidable({
    multiples: true,
    // 设置上传文件的保存目录
    uploadDir: __dirname + '/../public/images',
    // 保存文件后缀
    keepExtensions: true

  });

  form.parse(req, (err, fields, files) => {
    if (err) {
      next(err);
      return;
    }
    // console.log(fields);
    // console.log(files);
    // 服务器保存该图片的访问url
    let url = '/images/' + files.portrait.newFilename;//将来将此数据保存在数据库中
    res.send('ok')
    // res.json({ fields, files });
  });
', (req, res) => {
  // 创建form对象
  const form = formidable({
    multiples: true,
    // 设置上传文件的保存目录
    uploadDir: __dirname + '/../public/images',
    // 保存文件后缀
    keepExtensions: true

  });
  form.parse(req, (err, fields, files) => {
    if (err) {
      next(err);
      return;
    }
    // console.log(fields);
    // console.log(files);
    // 服务器保存该图片的访问url
    let url = '/images/' + files.portrait.newFilename;//将来将此数据保存在数据库中
    res.send('ok')
    // res.json({ fields, files });
  });
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

隐藏用户y

虽然不是很有才华,但是渴望打赏

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

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

打赏作者

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

抵扣说明:

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

余额充值