Koa is the next generation of Express’s Node.js-based Web framework. Built by the original Express team, koA uses async functions, discards callback functions, and significantly enhances error handling. Koa doesn’t bundle any middleware, giving it a clean feel, small size and clean programming.
Koa website link: koa.bootcss.com/
history
Express
Express is the most popular web framework of the first generation. It encapsulates the HTTP of Node.js and is used as follows:
var express = require('express');
var app = express();
app.get('/'.function (req, res) {
res.send('Hello World! ');
});
app.listen(3000.function () {
console.log('Server started successfully');
});
Copy the code
While the Express API is simple, it is based on ES5 syntax, and there is only one way to implement asynchronous code: a callback. If there are too many levels of asynchronous nesting, the code can be ugly to write:
app.get('/test'.function (req, res) {
fs.readFile('/file1'.function (err, data) {
if (err) {
res.status(500).send('read file1 error');
}
fs.readFile('/file2'.function (err, data) {
if (err) {
res.status(500).send('read file2 error');
}
res.type('text/plain');
res.send(data);
});
});
});
Copy the code
While you can use libraries like Async to organize asynchronous code, writing async with callbacks is just too painful!
koa1
With the new version of Node.js starting to support ES6, the Express team rewrote the next generation Web framework koA based on the GENERATOR of ES6. In contrast to Express, KOA 1.0 uses a generator for asynchrony and the code looks synchronous:
var koa = require('koa');
var app = koa();
app.use('/test'.function* () {
yield doReadFile1();
var data = yield doReadFile2();
this.body = data;
});
app.listen(3000.function () {
console.log('Server started successfully');
});
Copy the code
koa2
The KOA team didn’t stop at KOA 1.0, they were way ahead of the game with KOA2 based on ES7. Compared to KOA 1, KOA2 fully uses Promises with async to implement async.
app.use(async (ctx, next) => {
await next();
var data = await doReadFile();
ctx.response.type = 'text/plain';
ctx.response.body = data;
});
Copy the code
Koa development environment setup
Installation Node. Js
Since Node.js v7.6.0 fully supports async/await and does not require flags, node.js environments should be above 7.6.0. Node.js environment version v7.6 or later, NPM version 3.x or later.
Install Koa2
# install koa2 NPM install koaCopy the code
If the installation error, generally is the network speed problem, you can use CNPM to install.
hello Koa2
// In koA2, we import a class, so use uppercase Koa:
const Koa = require('koa')
// Create a Koa object representing the Web app itself:
const app = new Koa()
// For any request, app will call this asynchronous function to handle the request:
app.use( async ( ctx ) => {
ctx.body = 'hello koa2'
})
app.listen(3000)
console.log('Server started successfully')
Copy the code
On the command line, enter:
node index.js
Copy the code
Then type http://127.0.0.1:3000 into your browser to see the results.
Use the async/await
Quickly understand
Copy the following code, paste it in chrome’s console console, and press Enter to execute
function getSyncTime() {
return new Promise((resolve, reject) = > {
try {
let startTime = new Date().getTime()
setTimeout(() = > {
let endTime = new Date().getTime()
let data = endTime - startTime
resolve( data )
}, 500)}catch ( err ) {
reject( err )
}
})
}
async function getSyncData() {
let time = await getSyncTime()
let data = `endTime - startTime = ${time}`
return data
}
async function getData() {
let data = await getSyncData()
console.log( data )
}
getData()
Copy the code
Results:
From the above examples we can see the characteristics of async/await:
- Asynchronous logic can be written synchronously
- The bottom await returns a Promise object
- You can replace traditional callback nesting with synchronous writing of multiple async functions
Request data acquisition
GET Requests data acquisition
In KOA2, GET requests are received through request in two ways: Query and QueryString.
- Query: Returns a formatted argument object.
- Querystring: Returns a request string.
Since CTX has a direct reference to the request API, it is also possible to GET a GET request directly in CTX. CTX is also divided into Query and queryString.
const Koa = require('koa')
const app = new Koa()
app.use( async ( ctx ) => {
let url = ctx.url
// From the context's request object
let request = ctx.request
let req_query = request.query
let req_querystring = request.querystring
// Directly from the context
let ctx_query = ctx.query
let ctx_querystring = ctx.querystring
ctx.body = {
url,
req_query,
req_querystring,
ctx_query,
ctx_querystring
}
})
app.listen(3000.() = > {
console.log('Server started successfully')})Copy the code
The POST request parameters are obtained
For POST request processing, KOA2 does not encapsulate the method of obtaining parameters, which need to be obtained by parsing the native Node.js request object req in the context.
Steps to get a Post request:
- Parse the native Nodex.js object req in context CTX.
- Parse the POST form data into query String-strings (for example, user=jspang&age=18).
- Convert the string to JSON format.
Ctx. req is the node.js native HTTP request object provided by context, which can get more content and is suitable for our in-depth programming. Ctx. response is the encapsulated response object of the context, and ctx.res is the node.js native HTTP response object provided by the context.
Case code demo:
const Koa = require('koa')
const app = new Koa()
app.use( async ( ctx ) => {
if ( ctx.url === '/' && ctx.method === 'GET' ) {
// Return the form page when a GET request is made
let html = ` koa2 request post demo
`
ctx.body = html
} else if ( ctx.url === '/' && ctx.method === 'POST' ) {
// When a POST request is made, the data in the POST form is parsed and displayed
let postData = await parsePostData( ctx )
ctx.body = postData
} else {
// Other requests show 404
ctx.body = '404!
'}})// Parse the POST parameter of node's native request in context
function parsePostData( ctx ) {
return new Promise((resolve, reject) = > {
try {
let postdata = "";
ctx.req.addListener('data'.(data) = > {
postdata += data
})
ctx.req.addListener("end".function(){
let parseData = parseQueryStr( postdata )
resolve( parseData )
})
} catch ( err ) {
reject(err)
}
})
}
// Parse the POST request parameter string into JSON
function parseQueryStr( queryStr ) {
let queryData = {}
let queryStrList = queryStr.split('&')
console.log( queryStrList )
for ( let [ index, queryStr ] of queryStrList.entries() ) {
let itemList = queryStr.split('=')
queryData[ itemList[0]] =decodeURIComponent(itemList[1])}return queryData
}
app.listen(3000.() = > {
console.log('Server started successfully')})Copy the code
Koa – bodyparser middleware
For POST request processing, the KOA-BodyParser middleware parses formData from the KOA2 context into ctx.request.body
Installing middleware
// Install using NPM. Note that we use -save here, as it is required in production.
npm install --save koa-bodyparser@3
Copy the code
Introduction to use
// After the installation is complete, you need to import and use it in your code. We introduce it at the top of the code with require.
const bodyParser = require('koa-bodyparser');
Because the order of middleware is important, the KoA-BodyParser must be registered with the app object before the router.
app.use(bodyParser());
Copy the code
Ctx.request. body can be directly used to obtain the POST request parameters after being used in the code, which is automatically parsed by the middleware.
Now let’s optimize the example code:
const Koa = require('koa')
const app = new Koa()
const bodyParser = require('koa-bodyparser')
// Use ctx.body to parse middleware
app.use(bodyParser())
app.use( async ( ctx ) => {
if ( ctx.url === '/' && ctx.method === 'GET' ) {
// Return the form page when a GET request is made
let html = ` koa2 request post demo
`
ctx.body = html
} else if ( ctx.url === '/' && ctx.method === 'POST' ) {
// When a POST request is made, the middleware koa-BodyParser parses the data in the POST form and displays it
let postData = ctx.request.body
ctx.body = postData
} else {
// Other requests show 404
ctx.body = '< h1 > 404! '
}
})
app.listen(3000.() = > {
console.log('Server started successfully')})Copy the code
routing
Koa2 native route implementation
Simple example
To realize the native route, you need to obtain the path entered in the address bar and jump to the destination according to the different paths. This can be done with ctx.request.url. Let’s take a look at how to get access paths through a simple example.
const Koa = require('koa')
const app = new Koa()
app.use( async ( ctx ) => {
let url = ctx.request.url
ctx.body = url
})
app.listen(3000)
Copy the code
This time will visit http://127.0.0.1:3000/hello/12 page output/hello / 12. In other words, the url in the context of the request object is the name of the current access path. The required route can be customized according to ctx.request.url through certain judgment or regular matching.
Customized routes
Source file directory:
. ├ ─ ─ app. Js ├ ─ ─ package. The json └ ─ ─ the view ├ ─ ─ 404 HTML ├ ─ ─ index. The HTML └ ─ ─ todo. HTMLCopy the code
The implementation of native routing requires the introduction of fs modules to read files. Then according to the route path to read, and finally returned to the page, rendering. Let’s look at a little example.
/* app.js file */
const Koa = require('koa')
const fs = require('fs')
const app = new Koa()
/** * encapsulate asynchronous file-reading methods with Promise *@param {string} Page HTML file name *@return {promise} * /
function render( page ) {
return new Promise(( resolve, reject ) = > {
let viewUrl = `./view/${page}`
fs.readFile(viewUrl, "binary".( err, data ) = > {
if ( err ) {
reject( err )
} else {
resolve( data )
}
})
})
}
/** * Get HTML content from URL *@param {string} Url Indicates the URL of the KOA2 context, ctx.url *@return {string} Get the HTML file content */
async function route( url ) {
let view = '404.html'
switch ( url ) {
case '/':
view = 'index.html'
break
case '/index':
view = 'index.html'
break
case '/todo':
view = 'todo.html'
break
case '/ 404':
view = '404.html'
break
default:
break
}
let html = await render( view )
return html
}
app.use( async ( ctx ) => {
let url = ctx.request.url
let html = await route( url )
ctx.body = html
})
app.listen(3000.() = > {
console.log('Server started successfully')})Copy the code
Koa – the router middleware
If you rely on CTx.request. url to process routes manually, a lot of processing codes will be written. In this case, the middleware of the corresponding route is required to control the route
Install koA-Router middleware:
// The corresponding koA2 version is 7.x
npm install --save koa-router@7
Copy the code
Quick use of koA-Router:
const Koa = require('koa')
const app = new Koa()
const Router = require('koa-router')
// Child route 1
let home = new Router()
home.get('/'.async ( ctx )=>{
let html = `
`
ctx.body = html
})
// Child route 2
let page = new Router()
page.get('/ 404'.async ( ctx )=>{
ctx.body = '404 page! '
})
.get('/helloworld'.async ( ctx )=>{
ctx.body = 'helloworld page! '
})
// Load all child routes
let router = new Router()
router.use('/', home.routes(), home.allowedMethods())
router.use('/page', page.routes(), page.allowedMethods())
// Load the routing middleware
app.use(router.routes()).use(router.allowedMethods())
app.listen(3000.() = > {
console.log('Server started successfully')})Copy the code
The use of cookies
The CONTEXT of KOA (CTX) directly provides methods for reading and writing.
- Ctx.cookie. get(name,[optins]): Reads cookies in context requests.
- Ctx.cookie. set(name,value,[options]) : Writes cookies in context.
Write Cookie operation:
const Koa = require('koa');
const app = new Koa();
app.use(async(ctx)=>{
if(ctx.url=== '/index'){
ctx.cookies.set(
'MyName'.'FangC'
);
ctx.body = 'cookie is ok';
}else{
ctx.body = 'hello world'}}); app.listen(3000.() = > {
console.log('Server started successfully')})Copy the code
Cookie options
For example, if we want to store the user name and retain the login status of the user, you can choose not to log in within 7 days, or choose not to log in within 30 days. This requires configuring some options on the write:
- Domain: indicates the domain name of the cookie
- Path: indicates the path where the cookie is written
- MaxAge: indicates the maximum validity period of cookies
- Expires: indicates the cookie expiration time
- HttpOnly: Whether to obtain only from HTTP requests
- Overwirte: Indicates whether overwriting is allowed
const Koa = require('koa');
const app = new Koa();
app.use(async(ctx)=>{
if(ctx.url=== '/index'){
ctx.cookies.set(
'MyName'.'FangC', {domain:'127.0.0.1'.// Write the domain name of the cookie
path:'/index'.// Write the path to the cookie
maxAge:1000*60*60*24.// Cookie validity period
expires:new Date('2021-12-31'), // Cookie expiration time
httpOnly:false.// Whether to obtain only in HTTP requests
overwrite:false // Whether overwriting is allowed}); ctx.body ='cookie is ok';
}else{
ctx.body = 'hello world'}}); app.listen(3000.() = > {
console.log('Server started successfully')})Copy the code
Read the cookies:
const Koa = require('koa');
const app = new Koa();
app.use(async(ctx)=>{
if(ctx.url=== '/index'){
ctx.cookies.set(
'MyName'.'FangC', {domain:'127.0.0.1'.// Write the domain name of the cookie
path:'/index'.// Write the path to the cookie
maxAge:1000*60*60*24.// Cookie validity period
expires:new Date('2021-12-31'), // Cookie expiration time
httpOnly:false.// Whether to obtain only in HTTP requests
overwrite:false // Whether overwriting is allowed}); ctx.body ='cookie is ok';
}else{
if( ctx.cookies.get('MyName')){
ctx.body = ctx.cookies.get('MyName');
}else{
ctx.body = 'Cookie is none'; }}}); app.listen(3000.() = > {
console.log('Server started successfully')})Copy the code
Koa -static Static resource middleware
The installation
npm install --save koa-static
Copy the code
Create a new static folder and put images, CSS and JS files in the static folder.
use
const Koa = require('koa')
// Import the path package to concatenate paths
const path = require('path')
// Import the koa-static package
const static = require('koa-static')
const app = new Koa()
// Static resource directory for relative entry file index.js path
const staticPath = './static'
// Open folder __dirname is the directory of the currently running file
app.use(static(
path.join( __dirname, staticPath)
))
app.use( async ( ctx ) => {
ctx.body = 'hello world'
})
app.listen(3000.() = > {
console.log('Server started successfully')})Copy the code
A template engine
It is not possible to write all the HTML code in JS during development, which is obviously not practical, nor is it possible to accomplish large-scale Web development. We have to borrow the templating mechanism to help us develop, and koA2’s templating mechanism relies on middleware for development.
Installing middleware
npm install --save koa-views
Copy the code
Install ejS template engine
npm install --save ejs
Copy the code
Ejs template engine installed, you can write templates, for unified template management, we create a new view folder, and under it a new index.ejs file.
Article Contents:
├── ├─ ├─ ├─ download.txt ├─ ├─ download.txtCopy the code
The view/index ejs file
<! DOCTYPEhtml>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1><%= title %></h1>
<p>EJS Welcome to <%= title %></p>
</body>
</html>
Copy the code
. / index. Js file
const Koa = require('koa')
const views = require('koa-views')
const path = require('path')
const app = new Koa()
// Load the template engine
app.use(views(path.join(__dirname, './view'), {
extension: 'ejs'
}))
app.use( async ( ctx ) => {
let title = 'hello koa2'
await ctx.render('index', {
title,
})
})
app.listen(3000.() = >{
console.log('Server started successfully');
})
Copy the code
reference
Koa Node.js series – using EJS template engine