After reading this article, thoroughly understand koa and ejs

koa tutorial

1. Installation

Before developing koa2, the nodejs version is required to be higher than v7.6. Because nodejs7.6 fully supports async/await, so it can fully support koa2

Installation syntax: npm install koa --save-dev
Before using, first npm init initialization

2. Easy to use

var koa= require( ‘koa’);
var app= new koa();
//中间件,express中的req,res参数变成了ctx
app.use(async(ctx)=>{
    
        
   ctx.body=”你好koa2.x”
})
app.listen(3000);

Three, koa routing

3.1 Basic implementation
The routing in koa is different from express, we need to install the corresponding koa-router routing module to achieve

npm install koa-router --save-dev
imports:

var koa =require('koa');
var router=require('koa-router')();
var app=new koa();
//ctx 上下文context, 包含了request和response等信息
router.get('/', async (ctx) => {
    
    
   ctx.body=’首页’//相当于res.end( )
}).get('/news', async (ctx) => {
    
     //可以连续使用,也可以分开用
  ctx.body='这是一个新闻页面'
})
app.use(router.routes())//启动路由
app.use(router.allowedMethods()) 
//作用:这是官方文档的推荐用法,
//我们可以看到router.allowedMethods()用在了路由匹配router.routes()之后,
//所以在当所有路由中间件最后调用,此时根据ctx.status设置响应头
app.listen(3000)


3.2 How to get parameters by get value ?

Method 1: (recommended)
ctx.query // print {aid: '123'} to obtain an object (the most used method)
ctx.querystring // aid=123&name=zhangsan to obtain a string

Method 2: We can get the get value from the request in ctx
ctx.request.requery // {aid: '123'}
ctx.quest.querystring // aid=123&name=zhangsan

3.3 Dynamic Routing

router.get('/newscontent/:aid', async (ctx) => {
    
    
   console.log(ctx.params) // { aid : ‘123’}
   ctx.body = '新闻详情'
})

Dynamic routing can pass in multiple values

router.get('/newscontent/:aid/:cid', async (ctx) => {
    
    
   console.log(ctx.params) //{aid:’123’ , cid: ‘456’}
   ctx.body = '新闻详情'
})

Four, koa middleware

4.1 Middleware uses
Middleware functions:
Execute any code
Modify request and response objects
End request-response loop
Call the next middleware in the stack

If there is no next parameter in the get and post callback functions, the name will match the first route, and it will not match down. If you want to match down, you need to write next()

4.2 Application-level middleware
Definition: It is to operate a certain requirement before matching all routes

const Koa = require('koa');
const router = require('koa-router')();
const app = new Koa();
// 中间件,匹配任何路由,也就是在匹配任何路由之前调用它
app.use(async(ctx,next)=>{
    
     
    ctx.body="中间件"
    console.log(new Date())
    await next() // 当前路由匹配完成以后继续向下匹配,不写就不会向下匹配
})
router.get('/', async (ctx) => {
    
    
    ctx.body = '首页'
})
router.get('/news', async (ctx) => {
    
    
    ctx.body = '新闻'
})
app.use(router.routes()); //启动路由
app.use(router.allowedMethods())
app.listen(3000)

4.3 Routing middleware
Definition: Do some kind of operation before matching a specific route

router.get('/news', async (ctx,next) => {
    
    //匹配到news路由后继续向下匹配路由
  console.log(“新闻中间件”)
  await next()
})
router.get('/news', async (ctx) => {
    
    
    ctx.body = '新闻'
})

4.4 Error Handling Middleware
Express middleware and routes have a sequence, but koa has no order, even if it is placed at the end of the route, the middleware will be executed first

Example: 404 page

app.use(async(ctx,next)=>{
    
     
  	console.log('这是一个中间件01')
  	await next() 
	if(ctx.status==404){
    
    
	  ctx.status=404;
	  ctx.body="这是一个404页面"
	}else{
    
    
	  console.log('正常')
	}
})
router.get('/', async (ctx) => {
    
    
    ctx.body = '首页'
})

Print result: This is a middleware 01 -> Home -> Normal

Execution order, first print: This is a middleware 01, then execute the route under next(), after the route is executed and return the result, return to the app.use middleware, and execute the if judgment

· At this time, we will talk about the execution mode of koa

app.use(async(ctx,next)=>{
    
     
    console.log('中间件01')
    await next() 
    console.log('1')
})
app.use(async(ctx,next)=>{
    
     
    console.log('中间件02')
    await next() 
    console.log('2')
})
app.use(async(ctx,next)=>{
    
     
    console.log('中间件03')
    await next() 
    console.log('3')
})
 
 
router.get('/', async (ctx) => {
    
    
    ctx.body = '首页'
})
router.get('/news', async (ctx) => {
    
    
    console.log('匹配到新闻页面')
    ctx.body = '新闻'
})

Results of the:

Middleware 01 -> Middleware 02 -> Middleware 03 -> Match to news page -> 3 -> 2 -> 1

Koa is like an onion, execute request first, then execute response (from outside to inside, then from inside to outside)

As shown in the picture:
insert image description here

4.5 Third-party middleware

Five, ejs template engine

5.1 Install koa-views ejs
npm install koa-views --save
npm install ejs --save
5.2 use

const Koa = require('koa');
const views =require('koa-views')
const router = require('koa-router')();
const app = new Koa();
// app.use(views(__dirname + '/views', {map: {html: 'ejs'}})) 这种方式文件名得写index.html
app.use(views(__dirname+'/views', {
    
     extension: 'ejs' })) 这种写index.ejs
router.get('/', async (ctx) => {
    
    
  let title=”hello world
  let arr=[‘刚刚’,‘他娃儿噶’,‘大幅度’]
  await ctx.render('index',{
    
      //别忘了加 await
     title:title,
     arr:arr
  })
})

html part

<h1>这是一个ejs的模板引擎</h1>
<h2><%= title %></h2>
<ul>
   <% for(var i=0; i<arr.length; i++){
     
      %>
     <li><%= arr[i] %></li>
    <% }%>
</ul>

5.3 You can introduce the public header and footer
to create a new header.ejs file

I am a public header

Then introduce the 5.4 binding data nodejs part through <%- include('public/header.ejs') -%>
router.get('/', async (ctx) => {
    
    
    let content = '<h3>我是数据</h3>'
    await ctx.render('index',{
    
    
        content:content
    })
})

ejs part

<%=content%>
But this output is

i am data

, cannot parse

Label

At this time we need to use <%- %>

<%-content%> This is enough
5.5 Conditional judgment

router.get('/', async (ctx) => {
    
    
   let number=123
    await ctx.render('index',{
    
    
       number:number
    })
})

ejs part

<% if(number>20){%>
    <p>大于20</p>
    <%} else {%>
    <p>小于20</p>
<%}%>

5.6 How to configure public data
· What should I do if all pages need the same data?

Of course, you can also write one page per page, but if there are dozens or hundreds of pages, it will be too troublesome. At this time, we can define it in the ctx.state of the middleware

Example: For example, each page needs userInfo data

we can do this

nodejs part

app.use(anync (ctx,next) =>{
    
    
  	ctx.state.userInfo=”我是公共数据”
 	await next()
})

ejs call

<%=userInfo%>

Six, koa post submit data

6.1 nodejs natively implements
the ejs part of receiving form request data

<form action="/doAdd" method="post">
   <label for="">用户名:</label>
   <input type="text" name="username">
   <br>
   <label for="">密码:</label>
   <input type="password" name="password">
   <br>
   <button type="submit">确定</button>
</form>

nodejs part

const Koa = require('koa');
const views =require('koa-views')
const router = require('koa-router')();
const common =require('./module/common.js')
const app = new Koa();
 
app.use(views(__dirname+'/views', {
    
     extension: 'ejs' }))
router.get('/', async (ctx) => {
    
    
    await ctx.render('index.ejs')
})
 
router.post('/doAdd', async (ctx) => {
    
    
    var data= await common.getPostData(ctx)
    console.log(data)
    ctx.body=data;
 
})
 
app.use(router.routes()); //启动路由
app.use(router.allowedMethods())
app.listen(3000)

We created a new module folder and created a new common.js in it

Receive data requested by the client through node native code

A function getPostData is encapsulated in common.js

code show as below

exports.getPostData=function(ctx){
    
    
  return new Promise(function(resolve,reject){
    
    
    try{
    
    
      var str='';
      ctx.req.on('data',function(chunk){
    
    
         str+=chunk;
       })
      ctx.req.on('end',function(chunk){
    
    
         resolve(str)
      })
    }catch(err){
    
    
      reject(err)
    }
 })
}

6.2 koa-bodyparser obtains the data submitted by the form
①Install first

npm install koa-bodyparser --save
② import

const bodyParser = require('koa-bodyparser')
③ Configure koa-bodyparser middleware

app.use(bodyParser())
④ Get the data submitted by the form

The ctx.request.body
code is as follows

router.post(‘/doAdd’, async (ctx) => {
var data = ctx.request.body
ctx.body=data;
})

7. koa-static static resource middleware

Why use it?

Like a css file, it is invalid if it is only imported with a link. At this time, koa-static is used to process static resources

① Installation

npm install koa-static --save
② import

const static = require('koa-static')
③ Configuration, you can configure multiple

app.use(static(__dirname+'/static'))
First go to static to find, if found, return the corresponding file, if not found, then next()

Note: When the link is imported, do not write the external folder

For example: It is not allowed to write like this

Just write it like this

Similarly, there is no need to write static when importing pictures

Eight, art-template template engine (see official website)

art-template is a minimalistic, ultra-fast template engine.

It uses scope pre-declaration technology to optimize template rendering speed, so as to obtain running performance close to the limit of JavaScript, and supports NodeJS and browsers at the same time.

Use two ways of writing: ①similar to ejs ②similar to angular

render(app, { root: path.join(__dirname, 'view'), //view extname: '.art', //suffix debug: process.env.NODE_ENV !== 'production' //whether to enable debugging });



Nine, the use of cookies in koa

9.1 Introduction to cookies

A cookie is a variable stored on the visitor's computer

The http protocol is stateless

· The role of cookies

① Save user information

② Browser history

③ Guess your favorite function

④ Free login for 10 days

⑤ Data transfer between multiple pages

⑥ cookie implements shopping cart function

9.2 Set the value of the cookie in koa
ctx.cookies.set(name,value,[options])
Set the configuration of the value of the name in the cookie through options

cookie parameters

· Implement cookie sharing between multiple pages

router.get('/', async (ctx) => {
    
    
  ctx.cookies.set('userinfo','zhangsan',{
    
    
     maxAge:60*1000*60//多长时间以后过期
     path:/news’,//特定路径才能访问
    domain:.baidu.com’,
// 表示 a. baidu.com  b.baidu.com 可以共享cookie的数据, 
//正常情况下不要设置,默认就是当前域下面的所有页面都可以访问
      httpOnly:true , 
//true表示这个cookie只有服务器端可以访问(在页面中通过js访问不到),
//false表示服务端和都可以访问
    })
    await ctx.render('index.ejs')
})
router.get('/news', async (ctx) => {
    
    
    var cookdata = ctx.cookies.get('userinfo')
    ctx.body = cookdata;
})

9.3 The cookie bug in koa
· If the value of the cookie is set to Chinese, an error will be reported

router.get('/', async (ctx) => {
    
    
  ctx.cookies.set('userinfo',‘张三’,{
    
     //会报错
     maxAge:60*1000*60
  }}

Solution:

Use buffer to convert Chinese characters into base64 characters, and finally restore base64 to Chinese characters

router.get('/', async (ctx) => {
    
    
  var userinfo = new Buffer(‘张三’).toString(‘base64’)
  ctx.cookies.set('userinfo',userinfo ,{
    
    
    maxAge:60*1000*60                  
 })
  await ctx.render('index.ejs')
})
router.get('/news', async (ctx) => {
    
    
var cookdata = ctx.cookies.get('userinfo')
var userinfo = new Buffer(cookdata ,’base64’).toString()
    ctx.body = userinfo;
})

Guess you like

Origin blog.csdn.net/weixin_36557877/article/details/129316088