美文网首页
[后端开发]Node项目经验整理

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

作者: 杨山炮 | 来源:发表于2019-01-13 12:23 被阅读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端口")
    })
    

    相关文章

      网友评论

          本文标题:[后端开发]Node项目经验整理

          本文链接:https://www.haomeiwen.com/subject/yamdrqtx.html