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();//响应jsonres.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和iplet { url, ip } = req;// 将信息保存在文件中access.logfs.appendFileSync(path.resolve(__dirname, './access.log'), `${url}  ${ip}\r\n`);///home 127.0.0.1res.send('前台首页');
});

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

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

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

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

路由中间件实践

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

// 声明中间件
let checkCodeMiddleware = (req, res, next) => {// 判断URL中的是否code参数等于521if (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// 获取refererlet referer = req.get('referer');if (referer) {//有refer进入函数内,没有直接下一步// 实例化let url = new URL(referer);// 获取hostnamelet 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);// 服务器保存该图片的访问urllet 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);// 服务器保存该图片的访问urllet url = '/images/' + files.portrait.newFilename;//将来将此数据保存在数据库中res.send('ok')// res.json({ fields, files });});

express框架学习笔记相关推荐

  1. SpringMVC框架--学习笔记(下)

    接上篇:SpirngMVC框架--学习笔记(上):https://blog.csdn.net/a745233700/article/details/81038382 17.全局异常处理: 系统中异常包 ...

  2. SpringMVC框架--学习笔记(上)

    1.SpringMVC入门程序: (1)导入jar包:spring核心jar包.spring-webmvc整合Jar包 (2)配置前端控制器:web.xml文件中 <?xml version=& ...

  3. mybatis框架--学习笔记(下)

    上篇:mybatis框架--学习笔记(上):https://blog.csdn.net/a745233700/article/details/81034021 8.高级映射: (1)一对一查询: ①使 ...

  4. mybatis框架--学习笔记(上)

    使用JDBC操作数据库的问题总结: (1)数据库连接,使用时创建,不使用时立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能. 设想:使用数据库连接池管理数据库连接. (2) ...

  5. JavaSE中Map框架学习笔记

    前言:最近几天都在生病,退烧之后身体虚弱.头疼.在床上躺了几天,什么事情都干不了.接下来这段时间,要好好加快进度才好. 前面用了三篇文章的篇幅学习了Collection框架的相关内容,而Map框架相对 ...

  6. python表单提交的两种方式_Flask框架学习笔记之表单基础介绍与表单提交方式

    本文实例讲述了Flask框架学习笔记之表单基础介绍与表单提交方式.分享给大家供大家参考,具体如下: 表单介绍 表单是HTML页面中负责数据采集功能的部件.由表单标签,表单域和表单按钮组成.通过表单,将 ...

  7. php框架费尔康,GitHub - majixian/study-phalcon: phalcon(费尔康)框架学习笔记

    phalcon(费尔康)框架学习笔记 以实例程序invo为例(invo程序放在网站根目录下的invo文件夹里,推荐php版本>=5.4) 环境不支持伪静态网址时的配置 第一步: 在app\con ...

  8. [Spring+SpringMVC+Mybatis]框架学习笔记(四):Spring实现AOP

    上一章:[Spring+SpringMVC+Mybatis]框架学习笔记(三):Spring实现JDBC 下一章:[Spring+SpringMVC+Mybatis]框架学习笔记(五):SpringA ...

  9. Samza框架-----学习笔记

    Samza框架-----学习笔记 基本概念: 作业:是对一组输入流进行处理转化成输出流的程序. 分区: Samza的流数据单位既不是Storm中的元组,也不是Spark Streaming中的DStr ...

最新文章

  1. android下调试声卡驱动之概述
  2. close和shutdown的区别
  3. input python_Python input 使用
  4. javas的四种状态 无锁状态 偏向锁状态 轻量级锁状态 重量级锁状态
  5. php 什么时候传引用,什么时候在PHP中使用传递引用?
  6. Git如何进行版本回退
  7. python 拟牛顿法 求非线性方程_C语言实现迭代法求非线性方程的根
  8. lvs+keepalived+nginx+tomcat高可用高性能集群部署
  9. 服务器关闭重启后客户端socket能自动连接吗_用Python 撸一个 Web 服务器
  10. 苹果电脑查看python版本_Mac 如何修改系统默认 Python 版本?
  11. Ceres配置(vs2013+Win10)
  12. BITED数学建模七日谈之一:参加全国大学生数学建模比赛前你需要积累哪些
  13. tornado Python mysql_python tornado mysql 内容管理后台部署
  14. 电驴搜索服务器正在连接,电驴连接不上服务器导致无法搜索解决的方法介绍
  15. 临床数据库挖掘系列2-使用SEER.stat软件提取数据
  16. 菜鸟日记(yzy) 微信公众号网页的开发-websocket
  17. python爬取整个网页,教师节不知道给老师送什么?
  18. 西门子——好用的通讯仿真通讯工具NetToPLCsim
  19. Retbleed:针对英特尔和AMD处理器的推断性执行攻击
  20. python读取excel数据并进行数据可视化_用Python处理Excel的数据,并将之可视化

热门文章

  1. Java valueOf() 方法
  2. ARP网络欺骗——手机/平板/电脑欺骗测试
  3. CSDN注销账号、解绑手机、邮箱问题(已解决)
  4. 121. Best Time to Buy and Sell Stock买卖股票的最佳时机
  5. javascript字符串比较大小
  6. 动态规划入门——记忆化搜索
  7. 7-2 歌唱比赛计分 (15分)
  8. 单点定位matlab计算,matlabGPS单点定位程序设计报告.doc
  9. 前端get方式下载文件
  10. 整人脚本-连点50下弹窗的windows脚本