1.简单架设http服务
使用koa开发服务,只需要少许代码,就可以假设一个简易服务器
// 引入模块
const koa=require('koa');
// 创建koa实例
const app=new koa();
// 服务器监听端口
app.listen(3000)
/*
只需要三行代码,我们就可以构建一个简易的服务器.
打开浏览器,访问 http://127.0.0.1:3000 。你会看到页面显示"Not Found",表示没有发现任何内容。当然,这个服务器目前来说是什么也做不了的.
*/
(1)Context对象
Koa中提供了一个对象Context,表示一次对话的上下文.通过加工这个对象,我们可以控制返回给用户的内容
Context对象包含了原始node的http请求和http回复(即request和response);
app.use(axync (context)=>{
console.log(context)
})
context对象是我们操作控制请求与回复的关键对象,它其中包含了request对象和response对象.我们可以通过它去处理获取相应的url信息与返回客户端信息
一个简单的请求
// 引入核心模块
const koa=require('koa')
// 创建koa实例
const app=new koa()
// 使用中间件(路由)
app.use(async (context)=>{
// 通过context.body返回信息给客户端
context.body=context
})
// 监听端口号
app.listen(3000);
console.log('Server running at http://127.0.0.1:3000')
// 当我们运行程序后,访问 http://127.0.0.1:3000 后,我们将在页面上看到如下内容
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-onIb1cfL-1600687125350)(D:\Learn_notes\Koa\public\ctx.png)]
通过上面信息,我们可以看到,context对象中,context.response
代表 HTTP Response。同样地,context.request
代表 HTTP Request。
响应头类型
在koa中,通常默认返回的响应头类型是 “text/plain” 格式类型. 即 {“Content-Type”:“text/plain”}.若我们想根据客户希望接收的数据类型进行相应返回,则我们可以根据 context.request.accepts (类型) 方法判断请求头类型,然后再根据context.response.type方法设置相应的响应头信息
app.use (async 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';
}
});
/*
ctx:context
ctx.response.body可简写为ctx.body
ctx.response.type可简写为ctx.type
ctx.request.accepts('类型')可简写为ctx.accepts('类型');
*/
级联特性
在koa中,除了context对象外,还存在方法next,该方法用于我们跳转使用下一个中间件.
ctx即context.
当一个中间件调用next()函数时,该中间件将暂停执行next()函数后面的内容,转而跳转执行下一个中间件.
当跳转的中间件内容执行完毕后,将返回上一个中间件继续执行next()函数后面的内容.若 跳转的下一级中间件种也存在next()函数,则执行顺序相同next()函数调用
// 引入相关模块koa
const koa = require("koa");
// 创建koa实例对象
const app = new koa();
// 中间件1
app.use(async (ctx, next) => {
await next();
console.log(1)
const rt = ctx.response.get("X-Response-Time");
console.log(`${ctx.method} ${ctx.url} - ${rt}`);
});
// 中间件2
app.use(async (ctx, next) => {
const start = Date.now();
await next();
console.log(2)
const ms = Date.now() - start;
ctx.set("X-Response-Time", `${ms}ms`);
});
// 中间件3
app.use(async (ctx) => {
console.log(3)
ctx.body = "Hello World";
});
// 监听端口3000
app.listen(3000);
console.log("Server running at http://127.0.0.1:3000");
koa实例信息设置
应用程序设置是 app 实例上的属性,目前支持如下:
app.env 默认是 NODE_ENV 或 "development"
app.keys 签名的 cookie 密钥数组
app.proxy 当真正的代理头字段将被信任时
忽略 .subdomains 的 app.subdomainOffset 偏移量,默认为 2
app.proxyIpHeader 代理 ip 消息头, 默认为 X-Forwarded-For
app.maxIpsCount 从代理 ip 消息头读取的最大 ips, 默认为 0 (代表无限)
您可以将设置传递给构造函数:
const Koa = require('koa');
const app = new Koa({ proxy: true });
或动态的:
const Koa = require('koa');
const app = new Koa();
app.proxy = true;
koa设置cookies
cookies设置常用于设置用户登录时使用,通过返回cookies设置用户登录时间时长.
在koa种,我们通过上下文context调用设置cookies
语法为:context.cookies.set(name,value,{
domain: ‘设置使用的域名(如:‘127.0.0.1’)’, // 不推荐设置
path:‘设置访问那个路径可以读取cookies(如:’/index’)’, // 该项若不配置,则所有页面都可以访问cookies(推荐不设置)
maxAge:‘设置cookies有效时间(如:1000x60x60x24)’,
expires:cookies失效时间(如: new Date(‘2018-12-30’));
httpOnly:布尔值,设置是否仅http协议类型生效,
overwrite:布尔值,设置是否允许重写(推荐false)
})
注意:在koa中无法设置中文的name与value, 若我们想要通过变量的方式设置name与value,需要先将中文转换为base64类型
const userinfo =Buffer.from('张三').toString('base64'); // koa中没法直接设置中文的cookie,需先将中文转成base64
ctx.cookies.set('username',userinfo,{
.....配置信息
})
当我们想要获取时,使用cookies时,就需要将base64格式还原为中文
const username=Buffer.from(data,'base64').toString() //// 获取 cookie 还原成 中文
案例:
// 引入相关模块
const koa=require('koa')
const Router=require('koa-router')
// 创建实例对象
const app=new koa()
const router=new Router()
// 使用路由
router.get('/index',async (ctx,next)=>{
// 设置cookies
ctx.cookies.set('name','value',{
domain:'127.0.0.1', // 设置域名
path:'/index', // 访问/index路径时设置cookies
maxAge:1000*60*60*24, // 设置cookies时长为一个小时
expires:new Date('2020-9-30'), // 设置cookies过期时间
httpOnly:false, // 设置cookies是否只有http协议网络生效
overwrite:false, // 设置cookies是否允许重写
})
// 页面返回信息
ctx.body='设置cookies'
})
// 获取cookies
// router.get('/blog',async (ctx,next)=>{
// 通过ctx.cookies.get(name)方法获取cookies
if(ctx.cookies.get('name')){
ctx.body=ctx.cookies.get('name'); // 若存在cookies,则返回cookies值
}
ctx.body='Hello,Cookies'
})
app.use(router.routes()).use(router.allowedMethods()); // 启动路由
// 端口号监听
app.listen(3000,()=>{
console.log('Server running at http:127.0.0.1:3000')
})
2.koa的路由使用
koa的路由我们通过包koa-router来进行管理
安装命令:
npm install koa-router --save
或yarn add koa-router
安装好后,我们需要对它进行引入使用
// 引入模块
const koa=require('koa')
// 引入路由,创建实例
const Router=require('koa-router')
// 创建koa实例对象
const app=new koa()
// 创建路由实例
const router=new Router()
// 使用路由
router.get('/',(ctx.next)=>{
ctx.body="Hello,World"
})
router.post('/blog',(ctx,next)=>{
....相关操作
})
app.use(router.routes());// 启动路由
app.use(router.allowedMethods());
/*
* router.allowedMethods()作用: 这是官方文档的推荐用法,我们可以
* 看到 router.allowedMethods()用在了路由匹配 router.routes()之后,所以在当所有
* 路由中间件最后调用.此时根据 ctx.status 设置 response 响应头
*
*/
// 端口号监听
app.listen(3000)
koa中路由的重定向声明
在koa中,有时候我们需要设置访问某个路由时,会跳转到某个指定的路由界面,这时就需要路由重定向工作了.
我们通过路由实例对象的redirect(form,to)方法进行实现
const router=new Router()
router.redirect('/','/index'); // 设置访问'/'路由时,重定向为访问'/index'路由
koa通过koa-bodyparser中间件解析post请求
在开发中,我们想要解析post请求,往往需要先对post请求参数的接收做一些处理,这会花费我们大量时间,因此,需要通过一些中间件去进行处理,以减少我们的开发时间.
安装命令
npm install koa-bodyparser --save
使用时,我们同样需要加载这个中间件
// 引入模块
const koa=require('koa')
const bodyparser=require('koa-bodyparser')
// 创建koa实例
const app=new koa()
// 加载
app.use(bodyparser)
使用时(需要获取post请求带来的参数内容),我们通过ctx.request.body直接获取
const params=ctx.request.body;
例如:
// 引入相关模块
const koa = require("koa");
const Router = require("koa-router");
const bodyParser = require("koa-bodyparser");
// 创建实例对象
const app = new koa();
const router = new Router();
// 加载bodyparser中间件
app.use(bodyParser());
// 使用路由中间件
router
.get("/login", async (ctx, next) => {
ctx.body = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>登录</title>
</head>
<body>
<form action="/login" method="post">
<label for="username">
<span>账号:</span>
<input type="text" id="username" name="username" />
</label>
<label for="password">
<span>密码:</span>
<input type="password" name="password" id="password" />
</label>
<br>
<button type="submit">登录</button>
</form>
</body>
</html>
`;
})
.post("/login", async (ctx, next) => {
ctx.body = ctx.request.body;
});
// 启动路由
app.use(router.routes()).use(router.allowedMethods());
// 监听端口3000
app.listen(3000);
console.log("Server running at http:127.0.0.1:3000");
koa中声明使用路由层级(即嵌套路由-父子路由关系,如: ‘/index/news’)
1.配置全局路由层级(即所有路由页面都添加上一个父层级)
配置全局的路由父层级,我们只需要在实例化路由时,配置prefix属性即可
// 引入路由
const Router=require('koa-router')
// 实例化路由
const router=new Router({
perfix:'需要添加的父层级'
})
例如:
const router=new Router({
perfix:'/Liucy'
})
// 通过如上声明,当我们在使用路由时,系统会自动在路由前面添加 /Liucy 前缀
2.分别设置不同的父路由前缀
即为不同的页面设置其子路由的前缀,如:
主页下的新闻内容
‘/index/news’
博客页面下的信息内容
‘/blog/indfo’
对于不同层级的父子路由,我们通过实现不同的路由来进行使用
// 引入相关模块
const koa = require("koa");
const Router = require("koa-router");
// 创建koa实例对象
const app = new koa();
// 使用路由
const home = new Router(); // 创建首页路由实例
home
.get("/", async (ctx, next) => {
ctx.body = "首页";
})
.get("/news", async (ctx, next) => {
ctx.body = "首页下的new路由页面";
})
.get("/more", async (ctx, next) => {
ctx.body = "首页下的more路由页面";
});
const blog = new Router(); // 创建博客页面路由实例
blog
.get("/", async (ctx, next) => {
ctx.body = "博客";
})
.get("/info", async (ctx, next) => {
ctx.body = "博客下的info路由页面";
})
.get("/more", async (ctx, next) => {
ctx.body = "博客下的more路由页面";
});
// 挂职路由
const router = new Router();
router.use("/index", home.routes(), home.allowedMethods());
router.use("/blog", blog.routes(), blog.allowedMethods());
// 启动路由
app.use(router.routes()).use(router.allowedMethods());
// 监听端口
app.listen(3000);
console.log("Server running at http://127.0.0.1:3000");
3.koa中使用模板引擎 EJS 调用html,css
安装:
npm install koa-views --save
npm install ejs --save
使用ejs模板引擎,在语法上需要使用配套的模板引擎语法.同时我们在声明html文件内容时,文件的后缀名为 .ejs
列如: index.ejs
使用步骤
// 引入模板引擎
const koa=require('koa')
const views=require('koa-views');
const path=require('path'); // 引入node模块path,用于解析路径
// 实例化koa
const app=new koa()
// 声明使用ejs
app.use(views(path.join(__dirname,'./view'),{
extension:'ejs'
}))
// 然后我们就可以在路由中正式写结构代码
案例:
// 引入相关模块
const koa = require("koa");
const path = require("path");
const Router = require("koa-router");
const views = require("koa-views");
// 创建实例对象
const app = new koa();
// 声明使用ejs
app.use(
views(path.join(__dirname, "./view"), {
extension: "ejs",
})
);
// 使用路由
const home = new Router();
home
.get("/", async (ctx, next) => {
let title = "Hello,Koa"; // 声明一个变量
await ctx.render("index", { title: title }); // 将声明的变量传递到index文件中
})
.get("/news", async (ctx, next) => {
ctx.body = "新闻";
});
// 加载路由
const router = new Router();
router.use("/index", home.routes(), home.allowedMethods());
app.use(router.routes()).use(router.allowedMethods());
// 监听端口
app.listen(3000, () => {
console.log("Server running at http://127.0.0.1:3000");
});
4.静态资源引用(图片,css等文件)
安装
npm install koa-static --save
使用步骤
// 引入相关模块
const koa=require('koa')
const path=require('path')
const static=require('koa-static')
// 创建实例对象
const app=new koa()
// 声明允许访问的静态文件路径
const saticPath='静态文件路径'
// 加载路径
app.use(static(path.join(__dirname,staticPath)));
案例:
// 引入相关模块
const koa = require("koa");
const path = require("path");
const views = require("koa-views");
const static = require("koa-static");
const Router = require("koa-router");
// 创建实例对象
const app = new koa();
// 声明静态文件访问路径
const staticPath = "./static";
// 加载模板引擎
app.use(
views(path.join(__dirname, "./view"), {
extension: "ejs",
})
);
// 加载静态文件
app.use(static(path.join(__dirname, staticPath)));
// 使用路由
const home = new Router();
home
.get("/", async (ctx, next) => {
let title = "资源访问";
let img='/1e_1c.jpg' // 访问静态资源图片
await ctx.render("index", { title,img });
})
.get("/img", async (ctx, next) => {
ctx.body ='Hello,IMG'
});
// 实例化路由加载
const router = new Router();
router.use("/index", home.routes(), router.allowedMethods());
// 加载路由
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
console.log("Server running at http://127.0.0.1:3000");
});
4.在koa中,如何获取请求参数
(1)get请求传参获取
// http://域名:端口/路由?参数1&参数2&参数3
// 例如: http://127.0.0.1:3000/index?name=张三&age=18&sex=男
router.get('/index',async (ctx,next)=>{
// 获取请求参数,在get请求中,我们可以通过ctx.request.query或ctx.request.qeurystring方法获取
// ctx.request.query方法能够直接将请求参数转化为对应的对象形式(推荐使用)
ctx.body=ctx.request.query; // {name:'张三',age:18,sex:'男'}
// ctx,request.querystring方法则将请求参数按字符串形式获取
ctx.body=ctx.request.querystring; // 'name=张三&age=18&sex=男'
})
(2)get动态路由参数获取(’/index/:id’)
// http://域名:端口/路由/参数
// 例如: http://127.0.0.1:3000/company/2434453234
router.get('/company/:id',async (ctx.next)=>{
// 通过ctx.params获取
ctx.body=ctx.params; // {id:2434453234}
})
(3)post请求获取参数
在koa中,我们处理post请求参数通过中间件进行处理
npm install --save koa-bodyparser
使用时,只需将其加载在koa实例对象上即可
// 引入
const koa=require('koa')
const bodyParser=require('koa-bodyparser')
const app=new koa()
app.use(bodyParser())
// 然后在需要获取post请求参数的地方,通过ctx.request.body方法即可获取
// ctx,request.querystring方法则将请求参数按字符串形式获取
ctx.body=ctx.request.querystring; // 'name=张三&age=18&sex=男'
})
**(2)get动态路由参数获取('/index/:id')**
```js
// http://域名:端口/路由/参数
// 例如: http://127.0.0.1:3000/company/2434453234
router.get('/company/:id',async (ctx.next)=>{
// 通过ctx.params获取
ctx.body=ctx.params; // {id:2434453234}
})
(3)post请求获取参数
在koa中,我们处理post请求参数通过中间件进行处理
npm install --save koa-bodyparser
使用时,只需将其加载在koa实例对象上即可
// 引入
const koa=require('koa')
const bodyParser=require('koa-bodyparser')
const app=new koa()
app.use(bodyParser())
// 然后在需要获取post请求参数的地方,通过ctx.request.body方法即可获取