Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
Koa ¿ò¼Ü½Ì³Ì
 
  4422  次浏览      27
  2018-12-19
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÍøÂ磬±¾ÎÄ´ÓÁ㿪ʼ£¬Ñ­Ðò½¥½ø£¬½Ì»áÄãÈçºÎʹÓà Koa д³ö×Ô¼ºµÄ Web Ó¦Óá£Ã¿Ò»²½¶¼Óмò½àÒ×¶®µÄʾÀý£¬Ï£ÍûÈôó¼ÒÒ»¿´¾Í¶®¡£

Node Ö÷ÒªÓÃÔÚ¿ª·¢ Web Ó¦Óá£Õâ¾ö¶¨ÁËʹÓà Node£¬ÍùÍùÀë²»¿ª Web Ó¦Óÿò¼Ü¡£

Koa ¾ÍÊÇÒ»ÖÖ¼òµ¥ºÃÓÃµÄ Web ¿ò¼Ü¡£ËüµÄÌØµãÊÇÓÅÑÅ¡¢¼ò½à¡¢±í´ïÁ¦Ç¿¡¢×ÔÓɶȸߡ£±¾Éí´úÂëÖ»ÓÐ1000¶àÐУ¬ËùÓй¦Äܶ¼Í¨¹ý²å¼þʵÏÖ£¬ºÜ·ûºÏ Unix ÕÜѧ¡£

±¾ÎÄ´ÓÁ㿪ʼ£¬Ñ­Ðò½¥½ø£¬½Ì»áÄãÈçºÎʹÓà Koa д³ö×Ô¼ºµÄ Web Ó¦Óá£Ã¿Ò»²½¶¼Óмò½àÒ×¶®µÄʾÀý£¬Ï£ÍûÈôó¼ÒÒ»¿´¾Í¶®¡£

Áã¡¢×¼±¸

Ê×ÏÈ£¬¼ì²é Node °æ±¾¡£

$ node -v
v8.0.0

Koa ±ØÐëʹÓà 7.6 ÒÔÉϵİ汾¡£Èç¹ûÄãµÄ°æ±¾µÍÓÚÕâ¸öÒªÇ󣬾ÍÒªÏÈÉý¼¶ Node¡£

È»ºó£¬¿Ë¡±¾ÎĵÄÅäÌ×ʾÀý¿â¡££¨Èç¹û²»·½±ãʹÓà Git£¬Ò²¿ÉÒÔÏÂÔØ zip Îļþ½âѹ¡££©

$ git clone https://github.com/ruanyf/koa-demos.git

½Ó×Å£¬½øÈëʾÀý¿â£¬°²×°ÒÀÀµ¡£

$ cd koa-demos
$ npm install

ËùÓÐʾÀýÔ´Â룬¶¼ÔÚ demos Ŀ¼ÏÂÃæ¡£

Ò»¡¢»ù±¾Ó÷¨

1.1 ¼ÜÉè HTTP ·þÎñ

Ö»ÒªÈýÐдúÂ룬¾Í¿ÉÒÔÓà Koa ¼ÜÉèÒ»¸ö HTTP ·þÎñ¡£

// demos/01.js
const Koa = require('koa');
const app = new Koa();

app.listen(3000);

ÔËÐÐÕâ¸ö½Å±¾¡£

$ node demos/01.js

´ò¿ªä¯ÀÀÆ÷£¬·ÃÎÊ http://127.0.0.1:3000 ¡£Äã»á¿´µ½Ò³ÃæÏÔʾ"Not Found"£¬±íʾûÓз¢ÏÖÈκÎÄÚÈÝ¡£ÕâÊÇÒòΪÎÒÃDz¢Ã»ÓиæËß Koa Ó¦¸ÃÏÔʾʲôÄÚÈÝ¡£

1.2 Context ¶ÔÏó

Koa Ìṩһ¸ö Context ¶ÔÏ󣬱íʾһ´Î¶Ô»°µÄÉÏÏÂÎÄ£¨°üÀ¨ HTTP ÇëÇóºÍ HTTP »Ø¸´£©¡£Í¨¹ý¼Ó¹¤Õâ¸ö¶ÔÏ󣬾ͿÉÒÔ¿ØÖÆ·µ»Ø¸øÓû§µÄÄÚÈÝ¡£

Context.response.bodyÊôÐÔ¾ÍÊÇ·¢Ë͸øÓû§µÄÄÚÈÝ¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕûµÄ´úÂë¿´ÕâÀ¡£


// demos/02.js
const Koa = require('koa');
const app = new Koa();

const main = ctx => {
ctx.response.body = 'Hello World';
};

app.use(main);
app.listen(3000);

ÉÏÃæ´úÂëÖУ¬mainº¯ÊýÓÃÀ´ÉèÖÃctx.response.body¡£È»ºó£¬Ê¹ÓÃapp.use·½·¨¼ÓÔØmainº¯Êý¡£

Äã¿ÉÄÜÒѾ­²Âµ½ÁË£¬ctx.response´ú±í HTTP Response¡£Í¬ÑùµØ£¬ctx.request´ú±í HTTP Request¡£

ÔËÐÐÕâ¸ö demo¡£

$ node demos/02.js

·ÃÎÊ http://127.0.0.1:3000 £¬ÏÖÔھͿÉÒÔ¿´µ½"Hello World"ÁË¡£

1.3 HTTP Response µÄÀàÐÍ

Koa ĬÈϵķµ»ØÀàÐÍÊÇtext/plain£¬Èç¹ûÏë·µ»ØÆäËûÀàÐ͵ÄÄÚÈÝ£¬¿ÉÒÔÏÈÓÃctx.request.acceptsÅжÏһϣ¬¿Í»§¶ËÏ£Íû½ÓÊÜʲôÊý¾Ý£¨¸ù¾Ý HTTP Request µÄAccept×ֶΣ©£¬È»ºóʹÓÃctx.response.typeÖ¸¶¨·µ»ØÀàÐÍ¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/03.js
const main = ctx => {
if (ctx.request.accepts('xml')) {
ctx.response.type = 'xml';
ctx.response.body = '<data>Hello World</data>';
} else if (ctx.request.accepts('json')) {
ctx.response.type = 'json';
ctx.response.body = { data: 'Hello World' };
} else if (ctx.request.accepts('html')) {
ctx.response.type = 'html';
ctx.response.body = '<p>Hello World</p>';
} else {
ctx.response.type = 'text';
ctx.response.body = 'Hello World';
}
};

ÔËÐÐÕâ¸ö demo¡£

$ node demos/03.js

·ÃÎÊ http://127.0.0.1:3000 £¬ÏÖÔÚ¿´µ½µÄ¾ÍÊÇÒ»¸ö XML ÎĵµÁË¡£

1.4 ÍøÒ³Ä£°å

ʵ¼Ê¿ª·¢ÖУ¬·µ»Ø¸øÓû§µÄÍøÒ³ÍùÍù¶¼Ð´³ÉÄ£°åÎļþ¡£ÎÒÃÇ¿ÉÒÔÈà Koa ÏȶÁȡģ°åÎļþ£¬È»ºó½«Õâ¸öÄ£°å·µ»Ø¸øÓû§¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/04.js
const fs = require('fs');

const main = ctx => {
ctx.response.type = 'html';
ctx.response.body = fs.createReadStream('./demos/template.html');
};

ÔËÐÐÕâ¸ö Demo¡£

$ node demos/04.js

·ÃÎÊ http://127.0.0.1:3000 £¬¿´µ½µÄ¾ÍÊÇÄ£°åÎļþµÄÄÚÈÝÁË¡£

¶þ¡¢Â·ÓÉ

2.1 Ô­Éú·ÓÉ

ÍøÕ¾Ò»°ã¶¼Óжà¸öÒ³Ãæ¡£Í¨¹ýctx.request.path¿ÉÒÔ»ñÈ¡Óû§ÇëÇóµÄ·¾¶£¬ÓÉ´ËʵÏÖ¼òµ¥µÄ·ÓÉ¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/05.js
const main = ctx => {
if (ctx.request.path !== '/') {
ctx.response.type = 'html';
ctx.response.body = '<a href="/">Index Page</a>';
} else {
ctx.response.body = 'Hello World';
}
};

ÔËÐÐÕâ¸ö demo¡£

$ node demos/05.js

·ÃÎÊ http://127.0.0.1:3000/about £¬¿ÉÒÔ¿´µ½Ò»¸öÁ´½Ó£¬µã»÷ºó¾ÍÌøµ½Ê×Ò³¡£

2.2 koa-route Ä£¿é

Ô­Éú·ÓÉÓÃÆðÀ´²»Ì«·½±ã£¬ÎÒÃÇ¿ÉÒÔʹÓ÷â×°ºÃµÄkoa-routeÄ£¿é¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/06.js
const route = require('koa-route');

const about = ctx => {
ctx.response.type = 'html';
ctx.response.body = '<a href="/">Index Page</a>';
};

const main = ctx => {
ctx.response.body = 'Hello World';
};

app.use(route.get('/', main));
app.use(route.get('/about', about));

ÉÏÃæ´úÂëÖУ¬¸ù·¾¶/µÄ´¦Àíº¯ÊýÊÇmain£¬/about·¾¶µÄ´¦Àíº¯ÊýÊÇabout¡£

ÔËÐÐÕâ¸ö demo¡£

$ node demos/06.js

·ÃÎÊ http://127.0.0.1:3000/about £¬Ð§¹ûÓëÉÏÒ»¸öÀý×ÓÍêÈ«Ïàͬ¡£

2.3 ¾²Ì¬×ÊÔ´

Èç¹ûÍøÕ¾Ìṩ¾²Ì¬×ÊÔ´£¨Í¼Æ¬¡¢×ÖÌå¡¢Ñùʽ±í¡¢½Å±¾......£©£¬ÎªËüÃÇÒ»¸ö¸öд·ÓɾͺÜÂé·³£¬Ò²Ã»±ØÒª¡£koa-staticÄ£¿é·â×°ÁËÕⲿ·ÖµÄÇëÇó¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£


// demos/12.js
const path = require('path');
const serve = require('koa-static');

const main = serve(path.join(__dirname));
app.use(main);

ÔËÐÐÕâ¸ö Demo¡£

$ node demos/12.js

·ÃÎÊ http://127.0.0.1:3000/12.js£¬ÔÚä¯ÀÀÆ÷Àï¾Í¿ÉÒÔ¿´µ½Õâ¸ö½Å±¾µÄÄÚÈÝ¡£

2.4 ÖØ¶¨Ïò

ÓÐЩ³¡ºÏ£¬·þÎñÆ÷ÐèÒªÖØ¶¨Ïò£¨redirect£©·ÃÎÊÇëÇó¡£±ÈÈ磬Óû§µÇ½ÒԺ󣬽«ËûÖØ¶¨Ïòµ½µÇ½ǰµÄÒ³Ãæ¡£ctx.response.redirect()·½·¨¿ÉÒÔ·¢³öÒ»¸ö302Ìø×ª£¬½«Óû§µ¼ÏòÁíÒ»¸ö·ÓÉ¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/13.js
const redirect = ctx => {
ctx.response.redirect('/');
ctx.response.body = '<a href="/">Index Page</a>';
};

app.use(route.get('/redirect', redirect));

ÔËÐÐÕâ¸ö demo¡£

$ node demos/13.js

·ÃÎÊ http://127.0.0.1:3000/redirect £¬ä¯ÀÀÆ÷»á½«Óû§µ¼Ïò¸ù·ÓÉ¡£

Èý¡¢Öмä¼þ

3.1 Logger ¹¦ÄÜ

Koa µÄ×î´óÌØÉ«£¬Ò²ÊÇ×îÖØÒªµÄÒ»¸öÉè¼Æ£¬¾ÍÊÇÖмä¼þ£¨middleware£©¡£ÎªÁËÀí½âÖмä¼þ£¬ÎÒÃÇÏÈ¿´Ò»Ï Logger £¨´òÓ¡ÈÕÖ¾£©¹¦ÄܵÄʵÏÖ¡£

×î¼òµ¥µÄд·¨¾ÍÊÇÔÚmainº¯ÊýÀïÃæÔö¼ÓÒ»ÐУ¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/07.js
const main = ctx => {
console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`);
ctx.response.body = 'Hello World';
};

ÔËÐÐÕâ¸ö Demo¡£

$ node demos/07.js

·ÃÎÊ http://127.0.0.1:3000 £¬ÃüÁîÐоͻáÊä³öÈÕÖ¾¡£

1502144902843 GET /

3.2 Öмä¼þµÄ¸ÅÄî

ÉÏÒ»¸öÀý×ÓÀïÃæµÄ Logger ¹¦ÄÜ£¬¿ÉÒÔ²ð·Ö³ÉÒ»¸ö¶ÀÁ¢º¯Êý£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/08.js
const logger = (ctx, next) => {
console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`);
next();
}
app.use(logger);

ÏñÉÏÃæ´úÂëÖеÄloggerº¯Êý¾Í½Ð×ö"Öмä¼þ"£¨middleware£©£¬ÒòΪËü´¦ÔÚ HTTP Request ºÍ HTTP Response Öм䣬ÓÃÀ´ÊµÏÖijÖÖÖм书ÄÜ¡£app.use()ÓÃÀ´¼ÓÔØÖмä¼þ¡£

»ù±¾ÉÏ£¬Koa ËùÓеŦÄܶ¼ÊÇͨ¹ýÖмä¼þʵÏֵģ¬Ç°ÃæÀý×ÓÀïÃæµÄmainÒ²ÊÇÖмä¼þ¡£Ã¿¸öÖмä¼þĬÈϽÓÊÜÁ½¸ö²ÎÊý£¬µÚÒ»¸ö²ÎÊýÊÇ Context ¶ÔÏ󣬵ڶþ¸ö²ÎÊýÊÇnextº¯Êý¡£Ö»Òªµ÷ÓÃnextº¯Êý£¬¾Í¿ÉÒÔ°ÑÖ´ÐÐȨת½»¸øÏÂÒ»¸öÖмä¼þ¡£

ÔËÐÐÕâ¸ö demo¡£

$ node demos/08.js

·ÃÎÊ http://127.0.0.1:3000 £¬ÃüÁîÐд°¿Ú»áÏÔʾÓëÉÏÒ»¸öÀý×ÓÏàͬµÄÈÕÖ¾Êä³ö¡£

3.3 Öмä¼þÕ»

¶à¸öÖмä¼þ»áÐγÉÒ»¸öÕ»½á¹¹£¨middle stack£©£¬ÒÔ"ÏȽøºó³ö"£¨first-in-last-out£©µÄ˳ÐòÖ´ÐС£

×îÍâ²ãµÄÖмä¼þÊ×ÏÈÖ´ÐС£

µ÷ÓÃnextº¯Êý£¬°ÑÖ´ÐÐȨ½»¸øÏÂÒ»¸öÖмä¼þ¡£

...

×îÄÚ²ãµÄÖмä¼þ×îºóÖ´ÐС£

Ö´ÐнáÊøºó£¬°ÑÖ´ÐÐȨ½»»ØÉÏÒ»²ãµÄÖмä¼þ¡£

...

×îÍâ²ãµÄÖмä¼þÊÕ»ØÖ´ÐÐȨ֮ºó£¬Ö´ÐÐnextº¯ÊýºóÃæµÄ´úÂë¡£

Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£


// demos/09.js
const one = (ctx, next) => {
console.log('>> one');
next();
console.log('<< one');
}

const two = (ctx, next) => {
console.log('>> two');
next();
console.log('<< two');
}

const three = (ctx, next) => {
console.log('>> three');
next();
console.log('<< three');
}

app.use(one);
app.use(two);
app.use(three);

ÔËÐÐÕâ¸ö demo¡£

$ node demos/09.js

·ÃÎÊ http://127.0.0.1:3000 £¬ÃüÁîÐд°¿Ú»áÓÐÈçÏÂÊä³ö¡£

>> one
>> two
>> three
<< three
<< two
<< one

Èç¹ûÖмä¼þÄÚ²¿Ã»Óе÷ÓÃnextº¯Êý£¬ÄÇôִÐÐȨ¾Í²»»á´«µÝÏÂÈ¥¡£×÷ΪÁ·Ï°£¬Äã¿ÉÒÔ½«twoº¯ÊýÀïÃænext()ÕâÒ»ÐÐ×¢Ê͵ôÔÙÖ´ÐУ¬¿´¿´»áÓÐʲô½á¹û¡£

3.4 Òì²½Öмä¼þ

Æù½ñΪֹ£¬ËùÓÐÀý×ÓµÄÖмä¼þ¶¼ÊÇͬ²½µÄ£¬²»°üº¬Òì²½²Ù×÷¡£Èç¹ûÓÐÒì²½²Ù×÷£¨±ÈÈç¶ÁÈ¡Êý¾Ý¿â£©£¬Öмä¼þ¾Í±ØÐëд³É async º¯Êý¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/10.js
const fs = require('fs.promised');
const Koa = require('koa');
const app = new Koa();

const main = async function (ctx, next) {
ctx.response.type = 'html';
ctx.response.body = await fs.readFile('./demos/template.html', 'utf8');
};

app.use(main);
app.listen(3000);

ÉÏÃæ´úÂëÖУ¬fs.readFileÊÇÒ»¸öÒì²½²Ù×÷£¬±ØÐëд³Éawait fs.readFile()£¬È»ºóÖмä¼þ±ØÐëд³É async º¯Êý¡£

ÔËÐÐÕâ¸ö demo¡£

$ node demos/10.js

·ÃÎÊ http://127.0.0.1:3000 £¬¾Í¿ÉÒÔ¿´µ½Ä£°åÎļþµÄÄÚÈÝ¡£

3.5 Öмä¼þµÄºÏ³É

koa-composeÄ£¿é¿ÉÒÔ½«¶à¸öÖмä¼þºÏ³ÉΪһ¸ö¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/11.js
const compose = require('koa-compose');

const logger = (ctx, next) => {
console.log(`${Date.now()} ${ctx.request.method} ${ctx.request.url}`);
next();
}

const main = ctx => {
ctx.response.body = 'Hello World';
};

const middlewares = compose([logger, main]);
app.use(middlewares);

ÔËÐÐÕâ¸ö demo¡£

$ node demos/11.js

·ÃÎÊ http://127.0.0.1:3000 £¬¾Í¿ÉÒÔÔÚÃüÁîÐд°¿Ú¿´µ½ÈÕÖ¾ÐÅÏ¢¡£

ËÄ¡¢´íÎó´¦Àí

4.1 500 ´íÎó

Èç¹û´úÂëÔËÐйý³ÌÖз¢Éú´íÎó£¬ÎÒÃÇÐèÒª°Ñ´íÎóÐÅÏ¢·µ»Ø¸øÓû§¡£HTTP Э¶¨Ô¼¶¨ÕâʱҪ·µ»Ø500״̬Âë¡£Koa ÌṩÁËctx.throw()·½·¨£¬ÓÃÀ´Å׳ö´íÎó£¬ctx.throw(500)¾ÍÊÇÅ׳ö500´íÎó¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/14.js
const main = ctx => {
ctx.throw(500);
};

ÔËÐÐÕâ¸ö demo¡£

$ node demos/14.js

·ÃÎÊ http://127.0.0.1:3000£¬Äã»á¿´µ½Ò»¸ö500´íÎóÒ³"Internal Server Error"¡£

4.2 404´íÎó

Èç¹û½«ctx.response.statusÉèÖóÉ404£¬¾ÍÏ൱ÓÚctx.throw(404)£¬·µ»Ø404´íÎó¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£


// demos/15.js
const main = ctx => {
ctx.response.status = 404;
ctx.response.body = 'Page Not Found';
};

ÔËÐÐÕâ¸ö demo¡£

$ node demos/15.js

·ÃÎÊ http://127.0.0.1:3000 £¬Äã¾Í¿´µ½Ò»¸ö404Ò³Ãæ"Page Not Found"¡£

4.3 ´¦Àí´íÎóµÄÖмä¼þ

ΪÁË·½±ã´¦Àí´íÎó£¬×îºÃʹÓÃtry...catch½«Æä²¶»ñ¡£µ«ÊÇ£¬ÎªÃ¿¸öÖмä¼þ¶¼Ð´try...catchÌ«Âé·³£¬ÎÒÃÇ¿ÉÒÔÈÃ×îÍâ²ãµÄÖмä¼þ£¬¸ºÔðËùÓÐÖмä¼þµÄ´íÎó´¦Àí¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/16.js
const handler = async (ctx, next) => {
try {
await next();
} catch (err) {
ctx.response.status = err.statusCode || err.status || 500;
ctx.response.body = {
message: err.message
};
}
};

const main = ctx => {
ctx.throw(500);
};

app.use(handler);
app.use(main);

ÔËÐÐÕâ¸ö demo¡£

$ node demos/16.js

·ÃÎÊ http://127.0.0.1:3000 £¬Äã»á¿´µ½Ò»¸ö500Ò³£¬ÀïÃæÓб¨´íÌáʾ {"message":"Internal Server Error"}¡£

4.4 error ʼþµÄ¼àÌý

ÔËÐйý³ÌÖÐÒ»µ©³ö´í£¬Koa »á´¥·¢Ò»¸öerrorʼþ¡£¼àÌýÕâ¸öʼþ£¬Ò²¿ÉÒÔ´¦Àí´íÎó¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/17.js
const main = ctx => {
ctx.throw(500);
};

app.on('error', (err, ctx) =>
console.error('server error', err);
);

ÔËÐÐÕâ¸ö demo¡£

$ node demos/17.js

·ÃÎÊ http://127.0.0.1:3000 £¬Äã»áÔÚÃüÁîÐд°¿Ú¿´µ½"server error xxx"¡£

4.5 ÊÍ·Å error ʼþ

ÐèҪעÒâµÄÊÇ£¬Èç¹û´íÎó±»try...catch²¶»ñ£¬¾Í²»»á´¥·¢errorʼþ¡£Õâʱ£¬±ØÐëµ÷ÓÃctx.app.emit()£¬ÊÖ¶¯ÊÍ·Åerrorʼþ£¬²ÅÄÜÈüàÌýº¯ÊýÉúЧ¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/18.js`
const handler = async (ctx, next) => {
try {
await next();
} catch (err) {
ctx.response.status = err.statusCode || err.status || 500;
ctx.response.type = 'html';
ctx.response.body = '<p>Something wrong, please contact administrator.</p>';
ctx.app.emit('error', err, ctx);
}
};

const main = ctx => {
ctx.throw(500);
};

app.on('error', function(err) {
console.log('logging error ', err.message);
console.log(err);
});

ÉÏÃæ´úÂëÖУ¬mainº¯ÊýÅ׳ö´íÎ󣬱»handlerº¯Êý²¶»ñ¡£catch´úÂë¿éÀïÃæÊ¹ÓÃctx.app.emit()ÊÖ¶¯ÊÍ·Åerrorʼþ£¬²ÅÄÜÈüàÌýº¯Êý¼àÌýµ½¡£

ÔËÐÐÕâ¸ö demo¡£

$ node demos/18.js

·ÃÎÊ http://127.0.0.1:3000 £¬Äã»áÔÚÃüÁîÐд°¿Ú¿´µ½logging error¡£

Îå¡¢Web App µÄ¹¦ÄÜ

5.1 Cookies

ctx.cookiesÓÃÀ´¶Áд Cookie¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/19.js
const main = function(ctx) {
const n = Number(ctx.cookies.get('view') || 0) + 1;
ctx.cookies.set('view', n);
ctx.response.body = n + ' views';
}

ÔËÐÐÕâ¸ö demo¡£

$ node demos/19.js

·ÃÎÊ http://127.0.0.1:3000 £¬Äã»á¿´µ½1 views¡£Ë¢ÐÂÒ»´ÎÒ³Ãæ£¬¾Í±ä³ÉÁË2 views¡£ÔÙˢУ¬Ã¿´Î¶¼»á¼ÆÊýÔö¼Ó1¡£

5.2 ±íµ¥

Web Ó¦ÓÃÀë²»¿ª´¦Àí±íµ¥¡£±¾ÖÊÉÏ£¬±íµ¥¾ÍÊÇ POST ·½·¨·¢Ë͵½·þÎñÆ÷µÄ¼üÖµ¶Ô¡£koa-bodyÄ£¿é¿ÉÒÔÓÃÀ´´Ó POST ÇëÇóµÄÊý¾ÝÌåÀïÃæÌáÈ¡¼üÖµ¶Ô¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/20.js
const koaBody = require('koa-body');

const main = async function(ctx) {
const body = ctx.request.body;
if (!body.name) ctx.throw(400, '.name required');
ctx.body = { name: body.name };
};

app.use(koaBody());

ÔËÐÐÕâ¸ö demo¡£

$ node demos/20.js

´ò¿ªÁíÒ»¸öÃüÁîÐд°¿Ú£¬ÔËÐÐÏÂÃæµÄÃüÁî¡£

$ curl -X POST --data "name=Jack" 127.0.0.1:3000
{"name":"Jack"}

$ curl -X POST --data "name" 127.0.0.1:3000
name required

ÉÏÃæ´úÂëʹÓà POST ·½·¨Ïò·þÎñÆ÷·¢ËÍÒ»¸ö¼üÖµ¶Ô£¬»á±»ÕýÈ·½âÎö¡£Èç¹û·¢Ë͵ÄÊý¾Ý²»ÕýÈ·£¬¾Í»áÊÕµ½´íÎóÌáʾ¡£

2.3 ÎļþÉÏ´«

koa-bodyÄ£¿é»¹¿ÉÒÔÓÃÀ´´¦ÀíÎļþÉÏ´«¡£Çë¿´ÏÂÃæµÄÀý×Ó£¨ÍêÕû´úÂë¿´ÕâÀ¡£

// demos/21.js
const os = require('os');
const path = require('path');
const koaBody = require('koa-body');

const main = async function(ctx) {
const tmpdir = os.tmpdir();
const filePaths = [];
const files = ctx.request.body.files || {};

for (let key in files) {
const file = files[key];
const filePath = path.join(tmpdir, file.name);
const reader = fs.createReadStream(file.path);
const writer = fs.createWriteStream(filePath);
reader.pipe(writer);
filePaths.push(filePath);
}

ctx.body = filePaths;
};

app.use(koaBody({ multipart: true }));

ÔËÐÐÕâ¸ö demo¡£

$ node demos/21.js

´ò¿ªÁíÒ»¸öÃüÁîÐд°¿Ú£¬ÔËÐÐÏÂÃæµÄÃüÁÉÏ´«Ò»¸öÎļþ¡£×¢Ò⣬/path/to/fileÒª¸ü»»ÎªÕæÊµµÄÎļþ·¾¶¡£

$ curl --form upload=@/path/to/file http://127.0.0.1:3000
["/tmp/file"]

 

   
4422 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì