[后端开发]Node项目经验整理

2019-01-13  本文已影响0人  杨山炮

批量注册路由

假设在项目下的routes下有多个子路由文件user.js和blog.js,基本内容一致

//routes/blog.js
const router = require("koa-router")({"prefix":"/blog"});
router.get("/",async (ctx)=>{
    ctx.body = {
        message:"博客首页"
    }
});
router.get("/:id",async(ctx)=>{
    console.log("blog=====>",ctx.params.id)
});
module.exports = router;

定义批量注册路由的方法

//routes/index.js
const fs = require("fs");
const path = require("path");

module.exports = (app)=>{
    fs.readdirSync(__dirname).forEach(file=>{
        console.log("file=====>",file);
        if(file=="index.js"||file=="admin"){return;}
        const route = require(`./${file}`);
        app.use(route.routes()).use(route.allowedMethods());
    });
}

app.js主入口文件的代码

const Koa = require("koa");
const router = require("koa-router")();
const Routes= require("./routes/index");
const app = new Koa();

Routes(app)
// const user = require(("./routes/user.js"));
// const blog = require(("./routes/blog.js"));
// router.use("/user",user);
// router.use("/blog",blog);
// app.use(router.routes());
// app.use(router.allowedMethods());

app.listen(3001,()=>{
    console.log("路由批量注册测试")
});

遍历文件夹下文件内容

const getFileInfo = (filepath)=>{
    fs.readdir(filepath,(err,files)=>{
        if(err){
            console.log("files error")
        }else{
        files.forEach(file=>{
             const fileDir = path.join(filepath,file);
             fs.stat(fileDir,(err,stat)=>{
                var isFile = stat.isFile();
                var isDir = stat.isDirectory();
                if(isFile){
                    var  content = fs.readFileSync(fileDir,"utf-8");
                }
                if(isDir){
                         getFileInfo(fileDir)
                }
             });            
         });
        }
    })
}

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

1.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()
})
2.0 外部模块导入解决方案
// 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'],//前端请求头
}));

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

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
    }
 });

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

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

Koa2获取post数据

原生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;
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端口")
})
上一篇下一篇

猜你喜欢

热点阅读