[项目积累]后端项目之Koa2经验整理

1.0 koa配置跨域请求的解决方案

1.0.0 非模块解决方案
app.use(async function(ctx, next) {
  ctx.set("Access-Control-Allow-Origin", ctx.request.header.origin)
  ctx.set("Access-Control-Allow-Credentials", true);
  ctx.set("Access-Control-Max-Age", 86400000);
  ctx.set("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE");
  ctx.set("Access-Control-Allow-Headers", "x-requested-with, accept, origin, content-type");
  await next()
})
1.0.1 外部模块导入解决方案
// koa2跨域模块
const Cors = require("koa2-cors");
app.use(Cors({
  origin:function(ctx){
      console.log(ctx.url+"====koa");
      if(ctx.url==="/api"){
          return "*"//允许所有域名的请求
      }
      return "http://localhost:3000"//指定的请求域名+端口
  },
  exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],//表明服务器支持的所有头信息字
  maxAge: 5,
  credentials: true,//表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中
  allowMethods: ['GET', 'POST', 'DELETE'], //设置允许的HTTP请求类型
  allowHeaders: ['Content-Type', 'Authorization', 'Accept'],//前端请求头
}));

2.0 Axios 发送请的时将json类型转换成Form类型

6903052-fd3ba6cbab40ca78.jpg
axios在post请求的时候传递过去格式是json.jpg

上述问题造成koa解析后的数据格式不符合预料的形式

//ctx.req.on("data")时候的数据形式
{"uName":"是的规范的","uPwd":"sssssssssss"}
//字符串序列化结果:
{ '{"uName":"是的规范的","uPwd":"ssssssssssss"}': 'undefined' }

import Qs from "qs"
//qs.parse()将URL解析成对象的形式
//qs.stringify()将对象 序列化成URL的形式,以&进行拼接
axios({
      transformRequest:[function(data){
     //在请求之前对data传参进行格式转换
     data = Qs.stringify(data);
     return data;
    }],
    method:"post",
    url:"/reg",
    headers:{
     "Content-type":"application/x-www-form-urlencoded;charset=utf-8"
      },
    data:{
         uName:this.uName.value,
        uPwd: this.uPwd.value
    }
 });

3.0 qs.stringify() 和JSON.stringify()的区别

var obj = {"name":"yxl","age":25};
qs.stringify(obj)//name=yxl&age=25
JSON.stringify(obj)//'{"name":"yxl","age":25}'

4.0 Koa2获取post数据

4.0.1 原生Nodejs获取Post数据
// 解析上下文里node原生请求的POST参数
const parsePostData = (ctx,next)=>{
    return new Promise((resolve,reject)=>{
        try{
            let postData = "";
            // console.log(ctx);
            // 用原生的node req
            ctx.req.addListener("data",(chunk)=>{
                console.log(chunk)
                    postData+=chunk;
            });
            ctx.req.addListener("end",()=>{
                console.log(postData+"333");
                let parseData = parsePostQuery(postData);
                resolve(parseData);
            })
        }catch(err){
            reject(err);
        }
    });
}
//将POST请求参数字符串解析成JSON
const parsePostQuery = (str)=>{
    let parse2JsonObj  = {};
    let queryStrArr = str.split("&");
    console.log(queryStrArr)
    // ["name=yyy","age=25","sex=nv"]
    // arr.entries()返回数组的迭代对象[0,"str1"],[1,"str2"]
    for(let [index,queryString] of queryStrArr.entries()){
        let item  = queryString.split("=");
        parse2JsonObj[item[0]] = decodeURIComponent(item[1]);
    }
    return parse2JsonObj;
}
let Utils = {
    parsePostData,
    parsePostQuery
}
module.exports = Utils;
4.0.1 koa-body模块解决post请求
//home.ejs<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1><%=title%></h1>
    <form action="http://localhost:3002/multipleFile" method="post" enctype="multipart/form-data">
    多文件 <input type="file" name="file" id="file" value="" multiple="multiple" />
    <input type="submit" value="提交"/>
</form>
<hr>
<form action="http://localhost:3002/singleFile" method="post"  enctype="multipart/form-data">
    单文件 <input type="file" name="file2" id="file2" value=""  />
    <input type="submit" value="提交"/>
</form> 
<hr>
<form action="http://localhost:3002/textField" method="post" enctype="application/x-www-form-urlencoded">
   用户名 <input type="text" name="username"/>
    密码<input type="password"  name="pwd"/>
    <input type="submit" value="提交"/>
</form>
</body>
</html>
const Koa = require("koa");
const router = require("koa-router")();
// const bodyParse = require("koa-bodyParse");
const KoaBody = require("koa-body");
const views = require("koa-views");
const path = require("path");
const fs = require("fs");

const app = new Koa();
const tempPath = path.resolve(__dirname,"./views");
app.use(KoaBody({
    multipart:true,
    formidable: {
        maxFileSize: 200*1024*1024    // 设置上传文件大小最大限制,默认2M
    }
}));
app.use(views(path.resolve(__dirname,"./views"),{
    extension:"ejs"
}));
router.get("/",async (ctx,next)=>{
    let  title ="文件上传测试";
    await ctx.render("home",{title})
});
router.post("/singleFile",async (ctx,next)=>{
    console.log(ctx.request);
    let file = ctx.request.files.file2;
    console.log(file);
    // console.log(file);
    // 创建文件可读流
    let reader = fs.createReadStream(file.path);

    // 创建上传文件的存放位置
    let uploadPath = path.join(__dirname,"public/upload/")+`${file.name}`;
    // // 创建文件可写流
    // console.log(uploadPath);
    let write = fs.createWriteStream(uploadPath);
    // // 通过管道输出
    reader.pipe(write);
    await next();
    return ctx.body = "单个文件上传成功";
});
router.post("/multipleFile",async (ctx,next)=>{
    console.log(ctx.request.files);
    let files = ctx.request.files.file;
    for(let file of files){
        // 创建文件可读流
        let reader = fs.createReadStream(file.path);
        // 创建上传文件的存放位置
        let uploadPath = path.join(__dirname,"public/upload/")+`${file.name}`;
        // 创建文件可写流
        let write = fs.createWriteStream(uploadPath);
        // 通过管道输出
        reader.pipe(write);
        await next();
    }
    return ctx.body = "多个文件上传成功";
});
router.post("/textField",async(ctx ,next)=>{
        // console.log(ctx.request)
        ctx.body = JSON.stringify(ctx.request.body);
        console.log(ctx.request.body);
        await next();
});
app.use(router.routes());
app.listen("3002",()=>{
    console.log("监听这3002端口")
})

猜你喜欢

转载自blog.csdn.net/weixin_34138377/article/details/86996184