Koa跨域
// koa cors跨域
const cors = require('koa2-cors');
app.use(cors())Koa文件上传
npm i koa-multer -Sconst multer = require('koa-multer');
const { join } = require('path');
const storage = multer.diskStorage({
// 存储位置
destination: join(process.cwd(), './public/upload'),
// 文件名
filename(req, file, cd){
// const filename = file.originalname.split('.');
// cd(null, `${Date.now()}.${filename[filename.length-1]}`)
cd(null, `${Date.now()}_${file.originalname}`);
}
})
const upload = multer({storage});
router.post('/upload', upload.single("file"), ctx => {
console.log(ctx.req.file); // 注意数据存储在原始请求中
console.log(JSON.stringify(ctx.request.body));
ctx.body = {
ok: '上传成功',
data: {
message: '文件上传成功'
}
}
})除了koa-multer,还可以使用中间件koa-better-body处理文件上传以及表单处理
Koa错误处理
app.use(async (ctx,next) => {
try {
await next();
} catch(error) {
// 响应用户
ctx.status = error.statusCode || error.status || 500;
ctx.body = error.message;
// 触发应用层级错误事件
ctx.app.emit('error', error, ctx);
console.log('捕获到错误: ', error.message);
}
})app.on('error', async ctx => {
console.error('app 错误:', error.message);
// 再向上级抛出错误,会停止程序
// throw error;
})Koa校验
const bouncer = require('koa-bouncer');
app.use(bouncer.middleware());/**
* 定义校验规则
*/
const bouncer = require('koa-bouncer');
const val = async (ctx, next) => {
try{
// 自定义校验规则
const isUser = name => name === 'abcabc';
// 校验开始
ctx.validateBody('name')
.required('要求提供用户名')
.isString()
.trim()
.isLength(6, 16, '用户名长度为6~16位')
.check(isUser(ctx.vals.name),'Check Ok');
// 校验通过,放行
next();
} catch(error) {
if(error instanceof bouncer.ValidationError){
ctx.body = '校验失败' + error.message;
return;
}
throw error;
}
}
/**
* 使用koa-bouncer校验表单
*/
router.post('/', val, ctx => {
console.log('post /users');
const { body: user } = ctx.request; // 请求body
user.id = users.length+1;
users.push(user);
ctx.body = { ok: 1 };
});const bouncer = require('koa-bouncer');
router.post('/', async ctx => {
try{
// 输入验证码
const { code, to, expires } = ctx.session.smsCode;
ctx.validateBody('phone')
.required('必须提供手机号码')
.isString()
.trim()
.match(/1[3-9]\d{9}/, '手机号码不合法')
.eq(to, '请填写接收短信的手机号码');
ctx.validateBody('code')
.required('必须填写短信验证码')
.isString()
.trim()
.isLength(6, 6, '必须是6位验证码')
.eq(code, '验证码填写错误')
.checkPred(() => new Date() - new Date(expires) < 0, '验证码已过期');
ctx.validateBody('password')
.required('必须提供密码')
.isString()
.trim()
.match(/[a-zA-Z0-9]{6,16}/, '密码不合法');
// 入库,略
ctx.body = { ok: 1 };
} catch(error) {
if(error instanceof bouncer.ValidationError){
console.log(error);
ctx.status = 401;
} else {
ctx.status = 500;
}
ctx.body = { ok: 0, message: error.message };
}
})Koa验证码
const captcha = require('trek-captcha');
router.get('/captcha', async ctx => {
console.log('captcha: ', ctx.session.captcha);
const { token, buffer} = await captcha({size: 4});
// 一般将生产的验证码存储到session
ctx.session.captcha = token;
ctx.body = buffer;
})定时任务
const schedule = require('node-schedule');
function initSchedule(){
schedule.scheduleJob('*/3 * * * * *',handler(){
console.log('定时任务 三秒执行一次'+ new Date());
});
}