这几天天天搞到这么晚,我看明天的内容看起不多啊,不晓得为什么学着学着就到了这么晚。明天的内容还是有点多哈,有点自我矛盾了,再次一一道来。

1.

首先明天先看到路由的概念,什么叫做路由?

路由就是映射关系,在express中路由指的是客户端申请和服务器处理函数的映射关系,路由有三局部组成:申请类型、申请url和处理函数。

app.get(url,callback)其实就跟咱们后面所说的监听事件一样一一样的。

const express = require('express')const app = express()app.get('/', (req, res) => {    res.send('收到get申请')})app.listen(80, () => console.log('express server running at http://127.0.0.1'))  

这就是一个最简略的路由。路由的匹配过程,每当一个申请达到服务器器后,须要先通过路由匹配,当申请类型和url匹配胜利后才会调用前面的申请函数。、

用法

最简略的用法就是像咱们下面那样间接挂在实例上,这也是不举荐的,因为一个申请就要挂一个很麻烦很繁琐。

迷信的办法应该是创立路由模块。

分为五个步骤:

别离是创立路由js文件、调用express.Router创立路由对象、挂载路由、向外导出路有对象最初咱们的入口文件须要导入,在通过app.use去注册

// 1.导入expressconst express = require('express')// 2.创立路由对象const router = express.Router()// 3.挂载路由// 3.1挂载路由获取用户的信息router.get('/user/:id', (req,  res) => {    res.send(req.params)})// 3.2挂载路由承受用户发送的申请router.post('/post', (req, res) => {    res.send('post胜利')})// 4.向外共享路由成员module.exports = {    express,    router }
const express = require('./02模块化路由')const app = express.express()//  注册路由app.use(express.router)app.listen(80, () => console.log('express server running at http://127.0.0.1'))

这里说一下app.use昨天也看到了,他其实就是一个用来注册全局中间件的。而后咱们还能够为路由挂载前缀,也是通过app.use来增加办法同昨天根本一样

2.

中间件

指的是业务流程的两头解决环节。

就是当客户申请达到服务器后,可间断调用多个中间件对这个申请进行预处理,最初通过路由发送进去。

中间件的实质是一个函数根路有相似然而多了一个参数,next参数。

next是一个函数它的作用就是实现多个中间件间断调用的要害,把流转关系转给下一个中间件或者路由,每个中间件都有一个next一个转下去转到路由没有了就响应给客户端了。

2.1

咱们先看到全局失效的中间件,意思就是客户发动的任何申请,他都会触发,间接通过app.use来注册即可

const express = require('express')const app = express()// 中间件const mw = function(req, res, next) {    // res.send('这是中间件环节')    console.log('这是中慢慢环节')    next()}// 通过app。use定义为全局失效的中间件app.use(mw)app.get('/user', (req, res) => {    res.send('这是get申请')})app.post('/post', (res, req) => {    res.send('这是一个post申请')})app.listen(80, () => {    console.log('http://127.0.0.1');})

中间件的作用:

多个中间件共享同一个res和req,所以能够在上游的中间件定义好这些对象,上游间接用包含路由也能够用

怎么来定义多个全局中间件,间接通过app.use定义多个即可就像昨天所说的托管动态资源,有多个目录就注册多个

2.2

部分中间件

不是用app.use只对局部的路由无效,路由 的参数规定 也产生了扭转

const express = require('express')const app = express()const mw = function(req, res, next) {    req.time = Date.now()    next()}app.get('/', mw, (req, res) => {    res.send('部分失效' + req.time)})app.get('/user', (req, res) => res.send('没有失效') + req.time)app.listen(80, ()=> {    console.log('http://127.0.0.1');})

定义多个部分中间件

写多个函数过后在参数这里能够用逗号隔开,也能够间接写一个数组

有一个注意事项:就是肯定要在路由之前去注册中间件,不然路由执行完了谁还来执行中间件。

2.3

中间件的分类

①利用级别中间件

就是通过get、post、use绑定到app上的中间件

②路由级别中间件

就是在咱们方才的路由模块外面来交叉的一个中间件

③谬误级别中间件

这个有点说法

它是专门用来捕捉错误信息的而且形参变为了四个

他也是惟一一个卸载路由前面的中间件

const express = require('express')const { rename } = require('fs')const app = express()app.get('/', (req, res) => {    // 1.人为抛出一个谬误,一旦有错前面的响应就不会执行了    throw new Error('服务器外部产生谬误')    res.send('我不能执行进去')})// 2.谬误中间件app.use((err,req,res,next) => {    // 2.1向服务器打印谬误    console.log(err.message);    // 2.2向客户端发送谬误    res.send(err.message)    // 这样做 益处就是,后面如果产生了谬误导致了整个服务器曾经解体了,什么都执行不了了,这样一来,就能够失常输入错误信息,失常执行前面代码})app.listen(80, () => console.log('express server running at http://127.0.0.1'))

④内置中间件

三个内置的中间件别离是express.static这个曾经说过了后面

express.json这是拿来解析json格局数据的

express.urlencoded这是拿来解析urlencoded格局数据的

前面两个个别会配合req.body来拿申请体数据再给他们拿来解析了

const express = require('express')const app = express()// 留神这是中间件 所以必须配置到路由之前app.use(express.json())app.use(express.urlencoded({extended : false}))app.post('/', (req, res) => {    // 通过req.body能够拿到申请体数据    // postman在测试的时候抉择body外面的raw再把text抉择json就能够发送json数据了    console.log(req.body);    // 没有解析之前对于json数据是undefined})// 测试urlencoded数据体// 这个数据体的格局是x-www-form-urlencoded// 固定写法app.post('/user', (req, res) => {    // 没解析前时空对象    console.log(req.body);})app.listen(80, () => console.log('express server running at http://127.0.0.1'))

⑤第三方中间件 间接npm装置导入通过app.use注册即可应用

2.4

自定义中间件

这里做一个案例自定义一个相似于express.urlencoded性能的中间件能够解析申请体数据

const express = require('express')const app = express()// 4.利用node外面的一个内置模块解析申请体数据,在node外面内置了一个querystring模块是专门用来解决查问字符串的,这个模块提供的// parse()函数能够把查问字符串转换为对象const qs = require('querystring')// 1.定义中间件app.use((req, res, next) => {// 2.监听data事件,因为既然是服务器,那么必定会接管到癞子客户端的申请,如果有时候申请量过大,就会分批次传给服务器数据,所以data事件可能触发屡次// 就须要把每一次的数据最初拼接起来let str = ''req.on('data', chunk => {    str += chunk})// 3.req的end事件当申请体接管结束会主动登程end事件能够在这里解决残缺的申请体数据req.on('end', () => {    console.log(str);    str = qs.parse(str)    console.log(str);    // 5.解说洗出来的对象给到req.body    req.body = str    next()})})app.post('/', (req, res) => {    res.send(req.body)})app.listen(80, () => console.log('http://127.0.0.1'))

而后将自定义中间件进行了一个模块化

// 4.利用node外面的一个内置模块解析申请体数据,在node外面内置了一个querystring模块是专门用来解决查问字符串的,这个模块提供的// parse()函数能够把查问字符串转换为对象const qs = require('querystring')// 因为他人导入进来是间接注册应用所以能够把app开服务器等一些多余的代码省略就保留app.use外面的const bodyParse = (req, res, next) => {    // 2.监听data事件,因为既然是服务器,那么必定会接管到癞子客户端的申请,如果有时候申请量过大,就会分批次传给服务器数据,所以data事件可能触发屡次    // 就须要把每一次的数据最初拼接起来    let str = ''    req.on('data', chunk => {        str += chunk    })    // 3.req的end事件当申请体接管结束会主动登程end事件能够在这里解决残缺的申请体数据    req.on('end', () => {        console.log(str);        str = qs.parse(str)        console.log(str);        // 5.解说洗出来的对象给到req.body        req.body = str        next()    })}module.exports = bodyParse 
const bodyParse = require('./自定义中间件模块化')const express = require('express')const app = express()app.use(bodyParse)app.post('/', (req, res) => {    // res.send('收到get申请')    console.log(req.body);})app.listen(80, () => console.log('express server running at http://127.0.0.1'))  

3.

咱们持续看到用express来写接口

分为了三个步骤

创立根本服务器、创立 api路由模块、编写get接口

这是路由模块

// 2.写api路由模块 就是将路由模块化 因为那边引入进来须要用use来注册同时挂载api前缀const  express = require('express')const router = express.Router()// 3.编写get接口router.get('/get', (req, res) => {    // 3.1首先拿到用户传过来的数据    let data = req.query    // 3.2把数据发送给客户端    res.send({        status : 0, // 0示意胜利 1示意失败        msg : 'get申请胜利',        data : data //把数据返回给客户端    })})// 4.编写post接口router.post('/post', (req, res) => {    // 4.1客户端发过来的数据    let data = req.body    res.send({        status : 0,        msg :  'post申请胜利',        data : data    })})module.exports = router

其实次要就是通过req的那几个属性拿到数据后,再通过send办法发给客户端,上面是入口文件次要就是开启服务器,而后解析下数据

// 1.创立根本web服务器const express = require('express')const app = express()// 2.1导入路由模块 并挂载前缀const router = require('./router')// 4.2注册内置中间件 不然req.body解析不进去 app.use(express.urlencoded({extended : false}))// 5.cors解决跨域const cors = require('cors')app.use(cors())app.use('/api', router)app.listen(80, ()=> {    console.log('http://127.0.0.1');})

有些货色要把前面看了才晓得哈我只是先拿上来了。

4.

cors和jsonp

咱们方才这个案例其实是有bug的,就是有跨域的问题,咱们创立一个html文件通过button来获取数据这个时候就会因为协定不同而被同源策略组织。

咱们后面也说过解决跨域一个是cors一个是jsonp,这里必定不能用jsonp因为他只反对get,那么怎么来用cors呢?

间接三部曲装置导入加注册就解决了跨域问题了,就这么简略。

4.1

什么是cors

就是由一系列http响应头组成,同源策略碰到这个头就会解除限制。

cors个别是在服务器进行配置,客户端不须要。

上面是一些理解性内容

响应头部:

第一个res.setHeader(‘Access-Control-Allow-Orign’,‘http:wwwssss。聪慧、’)

这是示意只容许前面这个网站的域来拜访,如果为*那就示意容许任何域来拜访了

第二个是后面的根底上为Allow-Headers

咱们的cors默认值只有9个申请头如果超出了这个九个头就必然失败申请,在这个九个之外的能够通过这个代码来增加上来

第三个后面的根底上-Methods

cors默认只反对get post head 除此之外的须要用这个来设置。

4.2

当初不是理解内容了。

cors申请分类

大体上分为简略申请和预检申请。

什么叫做简略申请

满足两个条件:

一个是申请形式在默认的三个之内,一个是http申请头不能超过默认的九个

什么是预检申请

三个条件达到其中一种都是

一个是申请头在九个之外,一个是申请形式在三个之外,还有一个就是发送过去的数据是json数据

那么他们的区别是什么呢

很简略,简略申请只会发送一次申请,而预检申请会发送两次申请,为什么?

因为预检申请会在服务器与客户端正是连贯之前,提前发一个option的申请作为预检,看服务器是否跟这个格局的申请相连接,只有申请胜利了才会开始正式申请,携带实在数据。

5.

明天最初一个内容jsonp接口

首先要留神一下,如果说曾经配置了cors那么必须在配置cors之前去申明jsonp接口,不然会错乱的。

做这个接口之前咱们先来回应一下jsonp的一个常识,首先它是来解决跨域的,咱们通过script标签把函数传进来再去调用接口这种形式就叫jsonp

// 1.创立根本web服务器const express = require('express')const app = express()// 2.1导入路由模块 并挂载前缀const router = require('./router')// 4.2注册内置中间件 不然req.body解析不进去 app.use(express.urlencoded({extended : false}))// 6.jsonp接口必须写在coes之前app.get('/api/jsonp', (req, res) => {    // 6.1获取回调函数的名字    let fn = req.query.callback    // 6.2定义你要发送回去的数据对象    let data = {name : '张三', age : 15}    // 6.3模仿函数调用    let fnDiao = `${fn}(${JSON.stringify(data)})`    // 6.4数据返回回去    res.send(fnDiao)})// 5.cors解决跨域const cors = require('cors')const { json } = require('body-parser')app.use(cors())app.use('/api', router)app.listen(80, ()=> {    console.log('http://127.0.0.1');})