木灵鱼儿
阅读:2253
koa框架12 ctx属性
属性获取
属性 | 说明 | 可能的值 |
---|---|---|
method | 请求方法 | GET |
url | 完整请求路径 | /xxx/xxx/api?xxx=xxx |
path | 路径部分 | /xxx/xxx |
query | get参数 | {type:‘a’,p:12} |
querystring | get参数字符串 | ?type=a&p=12 |
host | 域名+端口 | localhost:8080 |
hostname | 域名 | localhost |
protocol | 协议 | http |
secure | 是否安全协议 | false |
ip | 访客ip地址 | xx.xx.xx.xx |
origin | 域:协议+域名+端口 | http://localhost:8080 |
其中我们可以通过ip属性写一个后台返回ip信息的api
ip信息api
由于我们要使用第三方的ip库地址,所以我们要使用http原生模块进行请求,请求是一个异步的,而我们koa都是使用async,实现异步语法同步写,所以我们要将这个请求封装成一个通用的ptomise
创建一个js文件,文件名自己想
const http = require("http");
module.exports = function(url) {
return new Promise((resolve, reject) => {
const req = http.request(url, res => {
let arr = [];
res.on("data", data => {
arr.push(data);
});
res.on("end", () => {
const buf = Buffer.concat(arr);
resolve(buf);
});
});
req.end();
//抛出错误
req.on("error", err => {
reject(err);
});
});
};
先引用http模块
模块化导出一个方法,方法接收一个url地址参数。
然后return出这个promise对象,在promise的回调里,我们创建http的网页请求request,两个参数,第一个为要请求的url地址,第二个为连接创建完毕后的回调函数。
request本身会返回一个request对象,我们本身只需要连接完毕就断开,不需要长期连接,所以使用end方法结束连接。
由于可能会产生错误,我们要使用on方法监听error事件,如果有,则使用promise的reject方法抛出错误。
连接进行时,我们的数据时一小段一小段的传输过来的,所以我们创建一个arr数组,监听request的res对象的data事件,每次触发我们就往数组里push传过来的data数据。
res对象再监听end事件,end事件触发表示数据传输完毕,我们可以进行操作了,由于传输都是二进制数据,而且又是数组保存,我们需要使用二进制对象 Buffer的concat方法,把数组连接成一长串二进制字符,然后将这个字符resolve传出去。
此时我们在后端引入这个promise中间件
const prom = require("./promise");
router.get("/", async ctx => {
const ip = ctx.ip;
const data = await prom(`http://ip-api.com/json/${ip}?lang=zh-CN`);
ctx.body = JSON.parse(data.toString());
});
我们await这个中间件方法,传入地址,等待他返回内容,data就会是其返回的二进制文件,我们再将它转为字符,由于返回的是json,所以用json的方法解析,然后给body,这样浏览器就能看到对应的信息了。
由于我们这个是异步操作,await本身也没有捕获错误能力,我们需要使用try来进行错误捕获。
router.get("/", async ctx => {
try {
const ip = ctx.ip;
const data = await prom(`http://ip-api.com/json/${ip}?lang=zh-CN`);
ctx.body = JSON.parse(data.toString());
} catch (e) {
ctx.body = "ip地址解析失败";
}
});
全局属性
ctx作为上下文对象,可以用于共享参数,官方提供了两个属性,一个为context和state。
context
context是在server对象上的,这个server就是new出来的Koa框架的构造函数所赋值的变量名,一般都用server这个变量名。
他类似于js中对象的prototype属性,在context上添加的属性,可以通过ctx对象调用。
const Koa = require("koa");
const Router = require("koa-router");
const server = new Koa();
server.listen(8080);
//创建路由
const router = new Router();
server.context.a = 12;
router.get("/", async ctx => {
console.log(ctx.a); //12
});
server.use(router.routes());
context一般用于添加一些通用的方法,比如上面我们自己写的promise封装文件。
用于扩展koa没有的方法或者属性。
state
state是作用于ctx对象的,也就是一个ctx的属性,官方意于如果所有的东西都写在context上,容易会发生覆盖,因为原来可能就已经有对应的名称了,而state则是一个空的对象,我们可以在里面添加任何东西都不用担心会覆盖原来的属性。
router.get("/", async ctx => {
ctx.state.login = true;
console.log(ctx.state.login); //true
});
特性检测
用于检测客户端是否支持某种数据,以及最优先的 选项
语言检测
检测客户端能支持什么样的语言,可以用来做全球化的多语言适配
const lang = ctx.acceptsLanguages(["zh","ja","en","fr"]);
lang会返回客户端都能接受参数里面最佳的语言。
acceptsLanguages中的参数,zh,en这些顺序都无所谓,随便,但是有两种传参方式,一种是传数组,数组里面有语言,第二种就是不要数组,两种方式都是等价的。
const lang = ctx.acceptsLanguages("zh","ja","en","fr");
数据类型
检测浏览器支持的最佳网页类型,这个一般都用不上,因为现在大家都知道,浏览器当然是html文件类型了。
const type = ctx.accepts("html","xhtml","jpg");
编码检测
用于检测浏览器支持什么编码,一般来讲,市面上的浏览器,99%都是支持gzip的。
const coding = ctx.acceptsEncodings("gzip","deflate","bz");
字符集检测
用于检测浏览器支持什么样的字符格式,当然是utf-8了啊,所以这个也用处不大
const charset = ctx.acceptsCharsets("utf-8","gb2312","big5");
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿 - 有梦就能远航站点。未经许可,禁止转载。
相关推荐
centos 安装最新版 node.js
[hide]先用yum 安装一次node先升级yum update 提示下载程序,回复y安装nodeyum install nodejsyum安装的node一般都不是最新的,所以我们还需要升级node的版本npm i n -g全局安装一个n插件n lts表示安装最新的稳定版!一些常用命令n ls查看已安装的node版本n rm 16.0.3删除16.0.3版本更多功能阅读插件文档:n等待安装完毕后,此时其实版本已经安装好了,但是输入node -v还是低版本,是因为centos的用户缓存问题。我们退出登录再登录就会刷新缓存了,此时的node -v输出的就是最新版本exit 退...
node npm yarn 如何同时运行多个指令
node的bash命令其实是有对应的指令字符的,但是,这个指令只能再linux,mac上才有生效,再windows是无效的,所以了解一下就行。命令说明&&顺序执行多条命令,当碰到执行出错的命令后将不执行后面的命令&并行执行多条命令||顺序执行多条命令,当碰到执行正确的命令后将不执行后面的命令|管道符windows上进行多命令"scripts": { "dev": "cross-env NODE_ENV=development webpack --env development --progress -...
koa教程2 HttpBearerAuth 传递token
前端发送token到后端,一般有三种方式:链接中携带token,query参数post这种请求body中携带token头信息携带token但是事实上http已经为我们提供了传token的方式,是一个相对来说比较安全的方式,就是HttpBearerAuth 其实他也是一个头信息来着,只是相对来说多了一点操作,在apipost软件中,我们可以直接可视化设置如果是axios,则是需要添加一个头信息:axios({ method: 'get', url: url, responseType: 'blob', headers: { 'Authoriz...

koa教程2 微信openid登录
微信的openid,前端登录时,会发送一个code码到后端,后端接收到这个code,然后配合appid、appsecret参数,像wx发送一个get请求。wx的请求地址:GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code具体查看文档:微信官方文档-服务端可以看到这段get请求有四个参数:属性类型默认值必填说明appidstring 是小程序 appIdsecretstring 是...
koa教程2 权限分级控制
在之前的代码中,我们使用了一个scope属性来表示用户的权限,但是scope是一个数字,他的阅读性是非常差的,当其他人开发的时候,可能并不知道你这个数字是什么意思?所以,我们需要将它转义成文本。为了方便判断,我们在enum.js中增加一个用户等级的对象enum.js://通用判断是否存在该类型 function isThisType(val) { let flag = false; Object.keys(this).find(key => { if (this[key] === val) { return flag = true; } })...
koa教程2 token鉴权
之前我们在token中传入我们的自定义参数,现在我们要做一个token鉴权,很简单,如果他的token合法,就可以访问这个路由,如果不合法,就打回。这个也不能说是真正意义上的鉴权,因为他还没有判断scope值,所以只能说是简单判断。做这个判断我们就可以通过中间件的形式,于是我们在middlewares目录下创建一个auth.js文件auth.js:const parseBearerToken = require("@utils/paresBearerToken"); const jwt = require("jsonwebtoken"); cons...
koa教程2 用户登录
登录类型用户注册之后,自然是用户登录,登录的时候我们需要考虑到登录的方式,往往在正式的项目里面,登录的方式可能会有很多种:账号密码登录手机号登录小程序一键登录那么我们登录的时候就要进行判断,设置一个type的属性,用于在登录时判断用户是什么类型的登录,这个由前端那边设定参数。type:1为账号密码登录,2为手机号登录,3为小程序一键登录作为判断,我们可以写一个查询表(枚举),在项目根目录创建一个lib目录,在里面创建一个enum.js文件。enum.js://通用判断是否存在该类型 function isThisType(val) { let flag = false; Obje...
node 自定义路径别名
用过vue cli的话,对路径中的@应该不陌生,他表示根目录,但是在node的环境里面,我们编写模块并引入时,并没有这种方便的写法。在node环境中,我们可以通过process.cwd()来表示根目录,但是这样的话,每次使用绝对路径引入,路径总是需要写一大堆拼接。const db = require(`${process.cwd()}/config/config`).database;这样略显麻烦,于是我们可以在全局写一个引入插件的方法:global.myRequire = function (path) { return require(`${process.cwd()}/${pa...
koa教程2 密码加密
默认情况下,我们通过User.create({ email, password, nickname });模型传入的数据,是无加密的,也就是说,在数据库中密码是明文显示的,这样肯定是不行,我们需要使用bcrypt插件进行加密yarn add bcryptjs --dev打开models/user.jsuser.js:const bcrypt = require("bcryptjs"); const { sequelize } = require(`${process.cwd()}/core/db`); const { Sequelize, Model, DataTy...

koa教程2 使用sequelize连接数据库,创建用户模型
数据库的连接处理,我们需要使用sequelize插件。这个插件还有对应的数据库驱动,如果是使用mysql,那么驱动是mysql2,具体可以查看中文版的入门教程:入门yarn add sequelize mysql2 --dev安装完成后我们先需要创建数据库连接。连接数据库在根目录/core目录**下创建一个db.js文件用于连接数据库。在连接数据库之前,我们需要一些数据库的参数,如账号,密码,端口,数据库名字,数据库地址,为了方便管理配置,我们在根目录创建一个config目录,里面存放一config.js文件 ,这个之前的教程我们就已经创建好了。config.js:module.expo...