L15-Node - Express

Express

原生 http 在某些方面不足以应对我们的开发需求,为了加快开发效率,就要使用框架开发

  • 第三方 Web 开发框架
  • 高度封装了 http 模块
  • 更加专注于业务,而非底层细节

安装和初始化

# 初始化(生成package.json文件)
npm init -y

# 安装
npm install express --save

入门案例

// 引入包
var express = require('express');

// 创建服务器应用,即原先的http.createServer()
var app = express();

// 公开指定的静态资源目录,客户端可以直接在浏览器访问该目录下的文件
app.use( '/public/', express.static('./public/') );

// 根据路径,执行不同的业务
app.get('/', function (req, res){
    res.send('hello world');
});
app.get('/about', function(req, res){
  	console.log(req.query);	// 解析请求的url地址,转化为对象{}
    res.send('about us');
});

// 监听3000端口
app.listen(3000, function(){
    console.log('app is running');
});

nodemon-自动重启服务器

使用第三方命令行工具:ndoemon 来解决频繁修改代码重启服务器的问题

nodemon 是一个基于node.js开发的第三方命令行工具,需要独立安装

只要是通过 nodemon xxx.js 启动的服务,就会监视文件的变化,当文件发生变化的时候(保存文件的时候),自动重启服务器

# 安装 nodemon
npm install -g nodemon  // 全局安装

# 使用nodemon
# 由原先的 node app.js 改为:
nodemon app.js

路由

基本概念

在 Express 中,路由指的是客户端的请求服务器处理函数之间的映射关系

Express 中的路由分 3 部分组成,分别是请求的类型请求的 URL 地址处理函数

路由 = 请求方法 + 请求路径 + 请求处理函数

语法

app.METHOD(PATH, HANDLER)

参数

  • METHOD - 请求方法
  • PATH- 请求路径
  • HANDLER - 请求处理函数

GET和POST请求

  • get以及获取get请求参数
// 以GET方法请求 / 的时候,执行对应的处理函数
app.get('/', function(req, res){
  // get方式获取url中的参数,返回的是对象类型{name: 'jack', age: 11}
  let urlParams = req.query;
  res.send('get request');
});
  • post以及获取post请求参数(需要第三方包 body-parser)
// 以POST方法请求 / 的时候,执行对应的处理函数
app.post('/', function(req, res){
  res.send('post request');
});

路由的匹配过程

每当一个请求到达服务器之后,需要先经过路由的匹配,只有匹配成功之后,才会调用对应的处理函数。

在匹配时,会按照路由的顺序进行匹配,如果请求类型和请求的 URL 同时匹配成功,则 Express 会将这次请求,转交给对应的 function 函数进行处理。

注意

  • 1、按照定义的先后顺序进行匹配
  • 2、请求类型和请求的URL同时匹配成功,才会调用对应的处理函数

模块化路由

为了方便对路由进行模块化的管理,Express 不建议将路由直接挂载到 app 上,而是推荐将路由抽离为单独的模块

将路由抽离为单独模块的步骤如下:

  • 1、创建路由模块对应的 .js 文件
  • 2、调用 express.Router() 函数创建路由对象
  • 3、向路由对象上挂载具体的路由
  • 4、使用 module.exports 向外共享路由对象
  • 5、使用 app.use() 函数注册路由模块

1、创建路由模块

// router/user.js

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

// 挂载具体的路由
router.get('/user', (req, res)=>{
    console.log( req.query ); // { name: 'Jack', age: '10' }
    res.send( 'GET 请求' );
});

router.post('/user', (req, res)=>{
    console.log( req.body );    // {}
    res.send( 'POST 请求' );
});

// 向外暴露路由
module.exports = router;

2、注册路由模块

// app.js

const express = require('express');
const app = express();
// 引入路由
const userRouter = require('./router/user.js');
...
// 挂载路由
app.use(userRouter);
...

3、为路由模块添加前缀

app.use('/api', userRouter);                         // 添加访问前缀 /api

静态资源托管-static

// 1. 当以 /public/开头的时候, 去 ./public/ 目录中找对应的资源(推荐使用,容易辨识)
app.use('/public/', express.static('./public/'));

// 2. 当省略第一个参数的时候,可以通过省略 /public 的方式来访问
// 		如:完整的url: localhost:3000/public/login.html
//          可以写成: localhost:3000/login.html 来访问资源
app.use(express.static('./public/'));

// 3. /a/ 可以看做是 ./public/的别名
// url访问路径:localhost:3000/a/login.html
app.use('/a/', express.static('./public/'));

app.use(express.static('files'));
app.use('/static', express.static(path.join(__dirname, 'public')));

中间件

中间件的概念

中间件(Middleware ),特指业务流程的中间处理环节。

Express中间件的调用流程

当一个请求到达 Express 的服务器之后,可以连续调用多个中间件,从而对这次请求进行预处理

Express 中间件的格式

Express 的中间件,本质上就是一个 function 处理函数,Express 中间件的格式如下:

注意:中间件函数的形参列表中,必须包含 next 参数。而路由处理函数中只包含 req 和 res。

next 函数的作用

next 函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由。

中间件的作用

多个中间件之间,共享同一份 req 和 res。基于这样的特性,我们可以在上游的中间件中,统一为 req 或 res 对象添加自定义的属性或方法,供下游的中间件或路由进行使用

// app.js
// 中间件
app.use( (req, res, next)=>{
+    req.inTime = Date.now();        // 将请求时的时间挂载到 req 的属性inTime上
    next();
} );

// 路由
app.get('/', (req, res)=>{
+    res.send( '首页' + req.inTime ); // 访问 req.inTime 
});
app.get('/user', (req, res)=>{
+    res.send( '用户页' + req.inTime ); // 访问 req.inTime 
});

中间件的使用

全局中间件

客户端发起的任何请求,到达服务器之后,都会触发的中间件,叫做全局生效的中间件

通过调用 app.use(中间件函数),即可定义全局生效的中间件

定义最简单的中间件函数

// app.js

// 1、定义最简单的中间件
let mv = (req, res, next)=>{
    console.log( '最简单的中间件' );
    // 处理业务

    // 注意:当前中间件业务处理完毕之后,必须调用 next() 函数,把流转关系交给下一个中间件或路由
    next();
}

全局生效的中间件(挂载中间件)

// app.js

// 2、将mv注册为全局生效的中间件
app.use(mv);

定义全局中间件的简化形式

// app.js
app.use((req, res, next)=>{
    console.log( '最简单的中间件' );
    // 处理业务

    // 注意:当前中间件业务处理完毕之后,必须调用 next() 函数,把流转关系交给下一个中间件或路由
    next();
});

定义多个全局中间件

可以使用 app.use() 连续定义多个全局中间件。客户端请求到达服务器之后,会按照中间件定义的先后顺序依次进行调用

// app.js
// 定义多个全局中间件
app.use((req, res, next)=>{
    console.log( '定义的第1个全局中间件' );
    next();
});
app.use((req, res, next)=>{
    console.log( '定义的第2个全局中间件' );
    next();
});

// 调用该路由之前,依次触发了上面2个全局中间件
app.get('/', (req, res)=>{
    res.send( 'GET Request' );
});

局部中间件

定义局部中间件

不使用 app.use() 定义的中间件,叫做局部生效的中间件

// app.js
// 局部中间件
let mw = (req, res, next)=>{
    console.log( '这是局部中间件' );
    next();
}

app.get('/', mw, (req, res)=>{  // 中间件mw只会影响该路由
    res.send( 'get / 请求' );
});

app.get('/user', (req, res)=>{  // 中间件mw不会影响该路由
    res.send( 'get /user 请求' );
});

定义和使用多个局部中间件

可以在路由中,通过如下两种等价的方式,使用多个局部中间件

app.get('/', mw1, mw2, (req, res)=>{
    res.send( 'get / 请求' );
});

app.get('/', [mw1, mw2], (req, res)=>{
    res.send( 'get / 请求' );
});

中间件的5个使用注意事项

  • 1、一定要在路由之前注册中间件
  • 2、客户端发送过来的请求,可以连续调用多个中间件进行处理
  • 3、执行完中间件的业务代码之后,不要忘记调用 next() 函数
  • 4、为了防止代码逻辑混乱,调用 next() 函数后不要再写额外的代码
  • 5、连续调用多个中间件时,多个中间件之间,共享 req 和 res 对象

中间件的分类

为了方便大家理解和记忆中间件的使用,Express 官方把常见的中间件用法,分成了 5 大类

  • 1、应用级别的中间件
  • 2、路由级别的中间件
  • 3、错误级别的中间件
  • 4、Express 内置的中间件
  • 5、第三方的中间件

应用级别的中间件

通过 app.use()app.get()app.post()绑定到 app 实例上的中间件,叫做应用级别的中间件

路由级别的中间件

绑定到 express.Router() 实例上的中间件,叫做路由级别的中间件

它的用法和应用级别中间件没有任何区别。只不过,应用级别中间件是绑定到 app 实例上,路由级别中间件绑定到 router 实例

错误级别的中间件

错误级别中间件的作用:专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题

格式:错误级别中间件的 function 处理函数中,必须有 4 个形参,形参顺序从前到后,分别是 (err, req, res, next)

注意:错误级别的中间件,必须注册在所有路由之后

Express 内置的中间件

自 Express 4.16.0 版本开始,Express 内置了 3 个常用的中间件,极大的提高了 Express 项目的开发效率和体验

  • 1、express.static - 快速托管静态资源的内置中间件,例如: HTML 文件、图片、CSS 样式等(无兼容性无需配置
  • 2、express.json - 解析 JSON 格式的请求体数据(有兼容性,仅在 4.16.0+ 版本中可用)
  • 3、express.urlencoded - 解析 URL-encoded 格式的请求体数据(有兼容性,仅在 4.16.0+ 版本中可用)

第三方的中间件

非 Express 官方内置的,而是由第三方开发出来的中间件,叫做第三方中间件

在项目中,大家可以按需下载并配置第三方中间件,从而提高项目的开发效率

例如:在 express@4.16.0 之前的版本中,经常使用 body-parser 这个第三方中间件,来解析请求体数据

使用步骤

  • 1、运行 npm install body-parser 安装中间件
  • 2、使用 require 导入中间件
  • 3、调用 app.use() 注册并使用中间件

注意:Express 内置的 express.urlencoded 中间件,就是基于 body-parser 这个第三方中间件进一步封装出来的

自定义中间件

需求

自己手动模拟一个类似于 express.urlencoded 这样的中间件,来解析 POST 提交到服务器的表单数据

步骤

  • 1、定义中间件
  • 2、监听 req 的 data 事
  • 3、监听 req 的 end 事件
  • 4、使用 querystring 模块解析请求体数据
  • 5、将解析出来的数据对象挂载为 req.body
  • 6、将自定义中间件封装为模块

1、定义中间件

使用 app.use() 来定义全局中间件

2、监听 req 的 data 事

在中间件中,需要监听 req 对象的 data 事件,来获取客户端发送到服务器的数据

如果数据量比较大,无法一次性发送完毕,则客户端会把数据切割后,分批发送到服务器。所以 data 事件可能会触发多次,每一次触发 data 事件时,获取到数据只是完整数据的一部分,需要手动对接收到的数据进行拼接

3、监听 req 的 end 事件

当请求体数据接收完毕之后,会自动触发 req 的 end 事件

我们可以在 req 的 end 事件中,拿到并处理完整的请求体数据

4、使用 querystring 模块解析请求体数据

Node.js 内置了一个 querystring 模块,专门用来处理查询字符串。通过这个模块提供的 parse() 函数,可以轻松把查询字符串,解析成对象的格式

5、将解析出来的数据对象挂载为 req.body

上游中间件、下游中间件、路由之间,共享同一份 req 和 res。因此,我们可以将解析出来的数据,挂载为 req的自定义属性,命名为 req.body,供下游使用

6、将自定义中间件封装为模块

router

导入的其他路由模块(见1.4 路由章节)

express.static()

静态资源托管(见1.5 静态资源托管-static 章节)

body-parser

获取表单post请求体 req.body 内容

在express中获取表单post请求体数据

在express中没有内置获取表单post请求体的API,需要使用第三方包 body-parser

注意

第三方中间件body-parser 已经在express@4.16.0版本中成为了内置中间件,配置如下

app.use( express.urlencoded({ extended: false }) );
app.use( express.json() );

以下为express@4.16.0版本之前的用法

安装

npm install body-parser --save

配置

var express = require('express');
// 1. 引入包
+ var bodyParser = require('body-parser');

var app = express();
// 2. 配置 body-parser
// 只要加入这个配置,就会在req请求对象上多出一个属性: body, 可以直接通过req.body来获取表单post请求体数据
+ app.use( bodyParser.urlencoded({ extended: false }) );
+ app.use( bodyParser.json() );

app.use(function(req, res){
  res.setHeader('Content-Type', 'text/plain');
  // 3. 可以直接通过req.body来获取表单post请求体数据
+  res.end(JSON.stringify(req.body, null, 2));
});

express处理404页面

express对于没有设定的请求路径,默认会返回 Can not get xxx

如果想要定制404页面,需要通过中间件配置

在自己的路由之后增加下面的代码

// 文件路径

app.use(function(req, res){
  // 所有未处理的请求路径都进入这里
  // 404
});

使用 Express 写接口

1、创建基本的服务器

// app.js
const express = require('express');	// 1、导入express
const app = express();				// 2、创建服务器实例 app
// TODO
app.listen(3000, ()=>{				// 3、监听3000端口,并启动服务器
    console.log( 'Server Running at http://127.0.0.1:3000' );
});

2、创建 API 路由模块

// router.js
const express = require('express');
const router = express.Router();

// 向外暴露 router
module.exports = router;
// app.js
// 中间件 - 配置
app.use(express.json());
app.use(express.urlencoded({extended: false}));

// 挂载路由
const router = require('./d14-router');
app.use('/api', router);

3、编写 GET 接口

// router.js
// GET 请求
router.get('/get', (req, res)=>{
    let query  = req.query;
    console.log( req1.body );
    res.send({
        status: 0,
        msg: '获取到 GET 请求',
        data: query
    });
});

4、编写 POST 接口

// router.js
// POST 请求
router.post('/post', (req, res)=>{
    let body = req.body;
    res.send({
        status: 0,
        msg: '获取到 POST 请求',
        data: body
    });
});

5、处理错误的请求路径

// router.js
// 处理错误的请求路径
router.use((req, res, next)=>{
    res.send({
        status: 1,
        msg: `没有匹配到 ${req.url} 请求`,
        data: {}
    });
});

6、处理错误

有了错误处理,当服务器出错时,系统就不会再崩溃,只是向前端发送了错误提示

// app.js
// 处理错误
app.use((err, req, res, next)=>{
    res.send({
        status: 2,
        msg: '出现错误',
        error: err.toString()
    });
});

跨域 - CORS

接口的跨域问题

刚才编写的 GETPOST接口,存在一个很严重的问题:不支持跨域请求

解决接口跨域问题的方案主要有两种:

  • CORS(主流的解决方案,推荐使用
  • JSONP(有缺陷的解决方案:只支持 GET 请求)

使用 cors 中间件解决跨域问题

cors 是 Express 的一个第三方中间件。通过安装和配置 cors 中间件,可以很方便地解决跨域问题。

使用步骤分为如下 3 步:

  • 1、运行 npm install cors 安装中间件
  • 2、使用 const cors = require('cors') 导入中间件
  • 3、在路由之前调用 app.use(cors()) 配置中间件

什么是 CORS

CORS (Cross-Origin Resource Sharing跨域资源共享)由一系列 HTTP 响应头组成,这些 HTTP 响应头决定浏览器是否阻止前端 JS 代码跨域获取资源

浏览器的同源安全策略默认会阻止网页“跨域”获取资源。但如果接口服务器配置了 CORS 相关的 HTTP 响应头,就可以解除浏览器端的跨域访问限制。

CORS 的注意事项

  • 1、CORS 主要在服务器端进行配置客户端浏览器无须做任何额外的配置,即可请求开启了 CORS 的接口。
  • 2、CORS 在浏览器中有兼容性。只有支持 XMLHttpRequest Level2 的浏览器,才能正常访问开启了 CORS 的服务端接口(例如:IE10+、Chrome4+、FireFox3.5+)。

CORS 响应头部 - Access-Control-Allow-Origin

响应头部中可以携带一个 Access-Control-Allow-Origin 字段,其语法如下:

Access-Control-Allow-Origin: <origin> | *

参数

  • origin - 指定了允许访问该资源的外域 URL
  • * - 允许来自任何域的请求

示例

// 表示只允许来自 百度 的请求
res.setHeader( 'Access-Control-Allow-Origin', 'http://baidu.com' );

// 允许来自任何域的请求
res.setHeader( 'Access-Control-Allow-Origin', '*' );

CORS 响应头部 - Access-Control-Allow-Headers

默认情况下,CORS 仅支持客户端向服务器发送如下的 9 个请求头

  • 1、Accept
  • 2、Accept-Language
  • 3、Content-Language
  • 4、DPR
  • 5、Downlink
  • 6、Save-Data
  • 7、Viewport-Width
  • 8、Width
  • 9、Content-Type (值仅限于 text/plain、multipart/form-data、application/x-www-form-urlencoded 三者之一)

如果客户端向服务器发送了额外的请求头信息,则需要在服务器端,通过 Access-Control-Allow-Headers 对额外的请求头进行声明,否则这次请求会失败!

CORS 响应头部 - Access-Control-Allow-Methods

默认情况下,CORS 仅支持客户端发起 GETPOSTHEAD 请求

如果客户端希望通过 PUTDELETE 等方式请求服务器的资源,则需要在服务器端,通过 Access-Control-Alow-Methods来指明实际请求所允许使用的 HTTP 方法

示例

CORS请求的分类

客户端在请求 CORS 接口时,根据请求方式请求头的不同,可以将 CORS 的请求分为两大类

  • 简单请求
  • 预检请求

简单请求

同时满足以下两大条件的请求,就属于简单请求:

  • 1、请求方式GETPOSTHEAD 三者之一
  • 2、HTTP 头部信息不超过以下10种字段:无自定义头部字段、Accept、Accept-Language、Content-Language、DPR、Downlink、Save-Data、Viewport-Width、Width 、Content-Type(只有三个值application/x-www-formurlencoded、multipart/form-data、text/plain)

预检请求

只要符合以下任何一个条件的请求,都需要进行预检请求:

  • 1、请求方式GETPOSTHEAD 之外的请求 Method 类型
  • 2、请求头包含自定义头部字段
  • 3、向服务器发送application/json 格式的数据

在浏览器与服务器正式通信之前,浏览器会先发送 OPTION 请求进行预检,以获知服务器是否允许该实际请求,所以这一次的 OPTION 请求称为“预检请求”。服务器成功响应预检请求后,才会发送真正的请求,并且携带真实数据。

简单请求预检请求区别

  • 1、简单请求的特点:客户端与服务器之间只会发生一次请求
  • 2、预检请求的特点:客户端与服务器之间会发生两次请求OPTION 预检请求成功之后,才会发起真正的请求

跨域 - JSONP 接口

JSONP 的概念与特点

概念:浏览器端通过 <script> 标签的 src 属性,请求服务器上的数据,同时,服务器返回一个函数的调用。这种请求数据的方式叫做 JSONP。

特点:

  • JSONP 不属于真正的 Ajax 请求,因为它没有使用 XMLHttpRequest 这个对象。
  • JSONP 仅支持 GET 请求,不支持 POST、PUT、DELETE 等请求。

创建 JSONP 接口的注意事项

如果项目中已经配置了 CORS 跨域资源共享,为了防止冲突必须在配置 CORS 中间件之前声明 JSONP 的接口。否则JSONP 接口会被处理成开启了 CORS 的接口。

实现 JSONP 接口的步骤

  • 1、获取客户端发送过来的回调函数的名字
  • 2、得到要通过 JSONP 形式发送给客户端的数据
  • 3、根据前两步得到的数据,拼接出一个函数调用的字符串
  • 4、把上一步拼接得到的字符串,响应客户端的script标签进行解析执行

实现 JSONP 接口的具体代码

在网页中使用 jQuery 发起 JSONP 请求

调用 $.ajax() 函数,提供 JSONP 的配置选项,从而发起 JSONP 请求,示例代码如下:

模板引擎整合

express + art-template

art-template的github仓库

art-template官方文档

安装

npm install art-template --save
npm install express-art-template --save

配置

// 参数1:当渲染以 .art 扩展名的文件的时候,使用art-template模板引擎
// 参数2:express-art-template 专门用来在express中把 art-template 整合到express中
// 这里虽然不需要加载art-template包,但是也必须安装,因为 express-art-template 依赖了 art-template
app.engine('art', require('express-art-template'))

// 可以修改成以html后缀名
app.engine('html', require('express-art-template'))

使用

// express为response对象提供了一个方法:render(),当配置了模板引擎时就可以使用render()
app.get('/', function(req, res){
  // 参数1: 不能写路径,默认会去项目中的views目录查找该模板文件
  // express有一个约定:把所有的视图模板文件都放在views目录中
  res.render('模板文件名', {模板数据});
});

修改默认的views视图渲染存储目录

app.set('views', '新的render函数的默认路径')

案例:用express重写留言本

app.js

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

let comments = [
    { username: '张三', message: '今天星期二!', dateTime: '2021-01-26 16:41:47' },
    { username: '李四', message: '你吃了吗?', dateTime: '2021-01-26 16:42:47' },
    { username: '王五', message: '还没有吃啊!', dateTime: '2021-01-26 16:43:47' },
    { username: '刘七', message: '是么', dateTime: '2021-01-26 16:44:47' }
];

let app = express();
// 公开静态资源目录
app.use( '/public/', express.static('./public/') );
// 配置模板引擎art-template
app.engine('html', require('express-art-template'));

// 配置body-parser,实现获取post请求体的数据
+ app.use(bodyParser.urlencoded({extented: false}));
+ app.use(bodyParser.json());

app.get('/', function(req, res){
    // 渲染模板引擎
    res.render('index.html', {
        comments: comments
    });
});

app.get('/post', function(req, res){
    res.render('post.html');
});

// app.get('/post_submit', function(req, res){
//     // 获取提交的参数,并保存到数组中
//     let comment = req.query;    // req.query 可以返回一个对象类型的url参数
//     comment.dateTime = '2021-1-27 21:23:43';
//     comments.unshift(comment);
    
//     res.redirect('/');
// });
app.post('/post', function(req, res){
    // 获取POST提交的参数,并保存到数组中
    // console.log(req.body);  // { username: '黑色冰凌', message: 'dada adad' }
+    let comment = req.body;
    comment.dateTime = '2021-1-27 21:23:43';
    comments.unshift(comment);
    
    res.redirect('/');
});

app.listen(3000, function(){
    console.log('server running...');
});

案例:增删改查

  • 代码

    D:\000\web20\15-Nodejs\day03\case03-student-manage-express

  • 起步

    • 初始化

      npm init -y
      npm i express --save
      npm i bootstrap --save
      npm i art-template --save
      npm i express-art-template --save
      npm i body-parser --save
      

    • 模板搭建

  • 路由设计

    请求路径 请求方法 get参数 post参数 备注
    /students get 渲染首页
    /students/add get 渲染添加学生页面
    /students/add post name,age,gender,hobbies 处理添加学生请求
    /students/edit get id 渲染编辑页面
    /students/edit post id,name,age,gender,hobbies 处理编辑请求
    /students/remove get id 处理删除请求
  • 入口模块 app.js

    • 创建服务

    • 配置相关服务

      • 配置模板引擎
      • 配置body-parser,解析post请求体参数
      • 提供静态资源服务
    • 注意:配置模板引擎和body-parser一定要在挂载路由之前

    • 挂载路由

      var router = require('./router');
      ...
      // 把路由挂载到app上
      app.use(router);
      

    • 监听端口,启动服务

  • 路由模块 router.js

    • 处理路由

      // 1. 引入express包
      var express = require('express');
      // 2. 创建一个路由容器
      var router = express.Router();
      ...
      // 3. 把路由都挂载到router这个路由容器中
      router.get('/', function(req, res){
        ...
      });
      ...
      // 4. 导出路由容器
      module.exports = router;
      

    • 根据不同的请求方法和请求路径处理不同的函数

      router.get('/', function(req, res){
        ...
      });
      
  • 模块职责要单一,不要乱写

    划分模块的目的就是为了提高项目代码的可维护性,提升开发效率

  • 数据保存到文件中

    • 先从文件中读取数据,转成对象
    • 向对象中push数据
    • 把对象转为字符串
    • 把字符串重新写入到文件中
  • 设计操作数据的API文件模块

    
    
  • 获取异步函数中返回的值

    // 如果需要获取一个函数中异步操作的结果,必须通过回调函数来获取
    + function fn(callback){
      setTimeout(function(){
        var data = 'hello';
    +    callback && callback(data);
        // 上面的相当于:
        // ( function(data){ console.log(data) } )()
      },1000);
    }
    
    + fn(function(data){
      console.log(data);
    });
    

数据库

MongoDB

MySQL

API

express

  • express.json() - 解析 JSON 格式的请求体数据
  • express.raw()
  • express.Router() - 创建路由对象
  • express.static() - 托管静态资源
  • express.text()
  • express.urlencoded() - 解析 URL-encoded 格式的请求体数据

app

  • Properties
    • app.locals
    • app.mountpath
  • Events
    • mount
  • Methods
    • app.get() - 处理GET请求的路由
    • app.post() - 处理POST请求的路由
    • app.put() - 处理PUT请求的路由
    • app.delete() - 处理DELETE请求的路由
    • app.use() - 注册全局中间件
    • app.engine() -
    • app.listen() - 启动服务器,监听服务器端口
    • app.all()
    • app.disable()
    • app.disabled()
    • app.enable()
    • app.enabled()
    • app.METHOD()
    • app.param()
    • app.path()
    • app.render()
    • app.route()
    • app.set()

req

  • Properties
    • req.app - 当callback为外部文件时,用req.app访问express的实例
    • req.baseUrl - 获取路由当前安装的URL路径
    • req.body - 获得请求主体(POST方法传递的参数)
    • req.cookies - 获得Cookies
    • req.fresh - 判断请求是否还新鲜,同req.stale
    • req.hostname - 获取主机名
    • req.ip - 获取IP地址
    • req.ips -
    • req.method - 获取请求方法
    • req.originalUrl - 获取原始请求URL
    • req.params - 获取URL中的动态参数/user/:id(GET方法传递的参数)
    • req.path - 获取请求路径
    • req.protocol - 获取协议类型
    • req.query - 获取URL的查询参数串(GET方法传递的参数)
    • req.route - 获取当前匹配的路由
    • req.secure
    • req.signedCookies
    • req.stale - 判断请求是否还新鲜,同req.fresh
    • req.subdomains - 获取子域名
    • req.xhr
  • Methods
    • req.on() - 监听request请求事件(data, end, error, close, readable, pause, resume)
    • req.accepts() - 检查可接受的请求的文档类型
    • req.acceptsCharsets() - 返回指定字符集的第一个可接受字符
    • req.acceptsEncodings() - 返回指定字符集的第一个可接受字符编码
    • req.acceptsLanguages() - 返回指定字符集的第一个可接受语言
    • req.get() - 获取指定的HTTP请求头
    • req.is() - 判断请求头Content-Type的MIME类型
    • req.param()
    • req.range()

res

  • Properties
    • res.app - 同req.app一样
    • res.headersSent
    • res.locals
  • Methods
    • res.append() - 追加指定HTTP头
    • res.attachment()
    • res.cookie(name,value [,option]) - 设置Cookie
    • res.clearCookie() - 清除Cookie
    • res.download() - 传送指定路径的文件
    • res.end() - 传送HTTP响应,并结束本次请求
    • res.format()
    • res.get() - 返回指定的HTTP头
    • res.json() - 传送JSON响应
    • res.jsonp() - 传送JSONP响应
    • res.links()
    • res.location() - 只设置响应的Location HTTP头,不设置状态码或者close response
    • res.redirect() - 设置响应的Location HTTP头,并且设置状态码302
    • res.render(view,[locals],callback) - 渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了
    • res.send() - 传送HTTP响应,并结束本次请求
    • res.sendFile() - 传送指定路径的文件 -会自动根据文件extension设定Content-Type
    • res.sendStatus()
    • res.set() - 设置HTTP头,传入object可以一次设置多个头。在res.append()后将重置之前设置的头
    • res.status() - 设置HTTP状态码
    • res.type() - 设置Content-Type的MIME类型
    • res.vary()

router

  • Methods
    • router.all()
    • router.METHOD()
    • router.param()
    • router.route()
    • router.use()
posted @ 2021-10-20 16:11  PikachuTT  阅读(34)  评论(0编辑  收藏  举报