|
3 |4 ?* v% k; z2 w# B+ i
Koa -- 基于 Node.js 平台的下一代 web 开发框架 - \2 A: Y# |3 C! X& k& m2 L; ^( ]
koa是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。 使用 koa 编写 web 应用,可以免除重复繁琐的回调函数嵌套, 并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件, 它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。开发思路和express差不多,最大的特点就是可以避免异步嵌套。koa2利用ES7的async/await特性,极大的解决了我们在做nodejs开发的时候异步给我们带来的烦恼。
?* A: l5 V+ A! _ 英文官网:http://koajs.com
8 B! R) {, ^. Z' y 中文官网:http://koajs.cn
, e+ O% O& P* A N4 Y0 K 1.koa d/ H* T& w& h1 J
安装koa包: npm i -S koa@latest
- ~) h& t2 l# u0 X% F+ u8 D 引入: const koa = require("koa"); 实例化对象: const app = new koa;
; s, N' \3 K6 O0 N+ ?% @ 通过实例操作,专门用于客户端请求的函数叫做中间件,使用use()注册
5 g0 y$ p8 t+ \2 q" E use()函数中必须使用异步 async; use可是调用无数次;
5 q8 o& x6 E2 r$ L+ W1 o 其中有两个参数: / W+ L) Y6 B$ D! _
a)ctx: 上下文环境,node的请求和响应对象,其中不建议使用node原生的req和res属性,使用koa封装的requset和response属性
" N x: V% J6 I# ?% @ b)next: next(),将本次控制权交给下一个中间件。
! @# b* m8 D+ } 最后一个中间件使用next()无意义,执行完控制权返回上一层,直至第一个。 $ D6 j5 u' d( F t) N
1. next参数的使用demo 4 C. @3 a" d$ k4 ]! R& R
`const Koa = require(``"koa"``);`
( B) J, ^# s- @ `const koa =` `new` `Koa();`
' ?9 r6 f V! L) ^' v `//中间件1` g- t# H5 x5 I- U7 ^
`koa.use(async (ctx, next) => {`! b2 c* A% o' D4 n! o0 `
`console.log(``"1 , 接收请求控制权"``);`
1 ]4 Q% P7 \; s" ]8 ?9 _' @- g `await next();` `//将控制权传给下一个中间件`
" n [8 d6 s7 s3 R `console.log(``"1 , 返回请求控制权"``);`# T8 |4 _; l* s x, \
`});` `//将中间件注册到koa的实例上`' ~$ F5 j+ B# z3 b+ X
`//中间件2`/ d2 v- n$ I# \4 b4 a- S
`koa.use(async (ctx, next) => {`
; P \1 x2 W$ c- H' N- F `console.log(``"2 , 接收请求控制权"``);`
; }9 t b( U) V! P: A await next();`
& G( Z# M5 X* M# Z0 v/ A `console.log(``"2 , 返回请求控制权"``);`
. c* A2 A9 b, b+ |6 v& |3 H `});`' ]3 `2 F. O% X9 D
`//中间件3`
% g8 [ l7 u! U `koa.use(async (ctx, next) => {`0 w6 | C. h m2 j2 z
`console.log(``"3 , 接收请求控制权"``);`
( G. N. x5 k2 _2 G `console.log(``"3 ,返回请求控制权"``);`
4 n$ Y/ E4 h0 B/ t- E3 T2 x `});`. o/ V& {! V- B! T0 a$ X, P0 l& h
`koa.listen(3000, ()=>{`! a1 X& K* k+ w, L& p
`console.log(``"开始监听3000端口"``);`/ g- N; z3 b$ X) e
`});`
) P& I. T& C, n' J 注:当中间件中没有next(),不会执行下面的中间件
$ e8 f5 z3 {( g 访问localhost:3000的效果图; 8 r7 Z" i1 e5 E- C/ D
/ j o( |- e$ e9 d
注:会有两次操作是因为图标icon也会请求一次
& G( q' W; n& U9 x/ |' Z7 c5 ^ 2.ctx参数的使用demo 9 g! X B& O( v
`const Koa = require(``"koa"``);`) f/ m9 U" e6 D$ X
`const koa =` `new` `Koa();`
4 ? }( V, O. e+ P% s% F `koa.use(async (ctx, next)=>{`) @1 d1 l6 b- g3 X7 _/ B: W! j
`ctx.body =` `"body可以返回数据,"``;`
9 K4 n3 n4 o% |+ L% A `ctx.body +=` `"可以多次调用,"``;`
U% i# F: Z* H" h% {7 Z `ctx.body +=` `"不需要end()"``;`
/ `$ b9 ` ^. P8 Y* m `});`* T( v0 `* v, g5 z: D |9 A
`koa.listen(3000, ()=>{`9 ~; O/ W: S# E/ T
`console.log(``"监听开始"``);`" K7 X# F0 V5 u# ]9 m! k
`});` - t( A6 C2 r b; \$ f8 `: K. t
效果:
2 G% O" c6 Y1 F9 z+ C3 ` U, k
* S. f6 k8 a1 m0 \( a# X' O& V+ z ctx.url ,ctx.path ,ctx.query ,ctx.querystring ,ctx.state ,ctx.type
7 G. Y' e5 z. M' E/ K `const Koa = require(``"koa"``);`+ n+ s5 Z+ ~! R& n1 Z+ j0 m5 W
`const koa =` `new` `Koa();`9 D& v0 ]- ^: G& m' C( w' f! D
`koa.use(async (ctx, next)=>{`
% E) R% y$ U- k& g" J `ctx.body = ctx.url;`
' t& D) {# { n% ~0 l9 z) t2 k _ `ctx.body = ctx.path;`
1 l3 D; {' z8 N; W; C `ctx.body = ctx.query;`: w' n, m& P' b7 D* j3 @
`ctx.body = ctx.querystring;`
3 x; b' ^6 w5 s+ A! p/ F, Z `});`2 `. E1 b8 f/ Z/ R3 j& p
`koa.listen(3000, ()=>{`$ B0 |* a5 x& f2 y, x$ d
`console.log(``"监听开始"``);`
8 a5 |/ f6 \5 t; I, g+ j `});` U5 q4 d$ P" K( n) Q7 n
访问http://localhost:3000/path?name=sjl&age=18为例,效果图:
0 c% [. ~; j, m$ E7 s 1. url: 整个路径 ' f3 U# _% _; ]* ]3 _' p& n7 R
& L4 s' n" Y+ S+ i; i" ?, A" E 2. path: 非查询部分 {% ?; d$ x% k9 _( N0 e
% U- w5 h$ y7 B( _: P. O 3. query: 将查询部分转为JSON对象 , z8 d' b7 B9 S* b1 @
! ~" v5 m. i7 H4 L- z 4. querystring: 将查询部分转为字符串
% u: ]( z a+ V7 f; v
. J) p% N! d h* X 5. ctx.state ,ctx.type 表示状态吗和类型
3 e# f$ w2 J1 K- ^& n: s 2.简单爬虫练习
8 B( C) ~1 ~& M" k8 |0 [/ ? 安装request,cheerio模块
7 W7 u8 e# \+ n `npm i -S request: 请求模块`
4 S4 ]& O/ B2 |$ G$ h9 q& A: x N# j `npm i -S cheerio: 抓取页面模块(JQ核心)`
5 x" U8 ?) b( E2 p5 A% Q% W7 e 抓取网页数据案例(随机网页) 4 _3 h7 r' `. L/ U$ O L- j: i. t
`//导入模块`2 d" H/ }4 R( i7 C! ]& C3 e& c
`const request = require(``"superagent"``);` `//导入请求模块`
4 r/ t: N. B0 X4 k `const cheerio = require(``"cheerio"``);`! Z1 C1 K. s$ l$ n9 F
`const {join} = require(``"path"``);`
! `- o, e. m; ? `const fs = require(``"fs"``);`1 k: m8 n9 d9 _2 z5 F3 j: c8 C
`let arr = [],` `//存放数据`
* X( p% E4 H$ U9 Z% q8 V9 }' r `reg = /\n|\s+/g,` `//replace中使用`1 [/ |1 X2 s9 R: d" E* a
`url =` `"[https://www.shiguangkey.com/course/search?key=%E5%89%8D%E7%AB%AF/](https://www.shiguangkey.com/course/search?key=%E5%89%8D%E7%AB%AF/)"``;` u2 ?. T' c8 w( T
`request`+ N. P, |4 p# }6 }" W% D, U$ c: u
`.get(url)`4 ? [ Z- Z0 P% ^: l+ `. A. ^
`.end((err, res) => {` Z! F6 X( A" a; ?9 A- R
`const $ = cheerio.load(res.text);` `//把字符串内的标签当成dom来使用`9 z d0 i3 Z* _ K
`$(``".course-item"``).each((i, v) => {`
' R( @8 g7 B3 [" q `// v当前进来的dom,根据网页的布局结构来找到准确的dom节点`
( _2 `0 F: s) {, H9 L) N7 A5 z: r `const obj = {`
; y$ z( _: \' Q$ a" y `imgSrc : $(v).find(``"img"``).prop(``"src"``),`
! H! O3 ]7 Y3 K$ u$ k `price : $(v).find(``".fr span"``).text().replace(reg,` `""``),`( O' R7 |" ]+ `3 k4 A; c- ^
`total : $(v).find(``".item-txt"``).text().replace(reg,` `""``),`9 {8 F' C8 l* L
`href : join(url + $(v).find(``".cimg"``).prop(``"href"``))`: b! {( f/ y. W% B) F# ]4 b
`};`
% t r5 b# f7 k `console.log(join(url + $(v).find(``".cimg"``).prop(``"href"``)));` `//拼接`
' M6 u) x8 m1 ~0 f' U. @5 _ `arr.push(obj);` `//把对象放进数组里`5 w8 a/ j! }# ]- Y3 w: o. K
`});`$ S. f3 G1 e& |$ F# ?
`fs.writeFile(``"./sjl.json"``, JSON.stringify(arr));` `//将爬到的数据写入文档中`
* b3 ~, q7 Z& ?# c( ]6 ~+ u' | `});`
) `6 J g5 v$ L5 e; K 以上就是本文的全部内容,希望对大家的学习有所帮助 5 Y, I" b: }2 y. C$ g
2 G! J2 d, Z( V3 O
" y& A5 L- _; k% {. L, l* q/ K' ~- V- v8 f, X/ C
7 [# j: k: O/ l& q6 j6 }
|