node-formidable源码:原生javascript解析前端传输的FormData

本系列文章是本人学习相关知识时所积累的笔记,以记录自己的学习历程,也为了方便回顾知识;故文章内容较为随意简练,抱着学习目的来的同学务必转移他处,以免我误人子弟~

参考资料:
酷勤网

在Koa和Express中,已经通过node-formidable模块替我们解析好了formdata数据,并分别将文件和表单字段(排除文件)存放在ctx.request.filesctx.request.body对象内。

通过阅读学习了node-formidable后,对解析的过程有了一定的理解,下面我们可以尝试着自己实现较为简单的解析工具

初步认识

  1. 启动项目
    地址:zyhcool: node-formidable
    启动:node myExperiment/server.js
  2. 打开浏览器,输入地址:http://localhost:3000/
  3. 填写完表单和选择文件,点击“upload”
  4. 查看myExperiment/data.txt和控制台输出

结果如下:

// myExperiment/data.txt
------WebKitFormBoundarywA1wAy4KrejGYQgv
Content-Disposition: form-data; name="title"

test
------WebKitFormBoundarywA1wAy4KrejGYQgv
Content-Disposition: form-data; name="upload"; filename="007Tv3Vmly1g7b1zq1xp4j31hc0u0ais.jpg"
Content-Type: image/jpeg

����(一堆乱码,二进制)

......

------WebKitFormBoundarywA1wAy4KrejGYQgv--
1| 
2| 
3| 
4| 
5| 
6| 

从结果来看,我们能得到一些信息:

  1. ------WebKitFormBoundarywA1wAy4KrejGYQgv是boundary(边界字符串),共有3个,其中头尾分别一个(尾部的boundary多了--);中间那个是titleupload两个字段的boundary
  2. 前端是以二进制流的形式传输formdata数据,而node将其转为Buffer数据
  3. 浏览器分6次才把完整数据全部传到后端
  4. 第一个Buffer开头的6个2d-的ASCII值的16进制,实际上,``转为ASCII值后是'2d', '2d', '2d', '2d', '2d', '2d', '57', '65', '62', '4b', '69', '74', '46', '6f', '72', '6d', '42', '6f', '75', '6e', '64', '61', '72', '79', '77', '41', '31', '77', '41', '79', '34', '4b', '72', '65', '6a', '47', '59', '51', '67', '76' ]
    跟第一个Buffer的值相比,你是不是发现了什么?
    2d 2d 2d 2d 2d 2d 57 65 62 4b 69 74 46 6f 72 6d 42 6f 75 6e 64 61 72 79 77 41 31 77 41 79 34 4b 72 65 6a 47 59 51 67 76 0d 0a 43 6f 6e 74 65 6e 74 2d … >
  5. formidable 就是根据Buffer中的16进制数找到boundary和实际数据所在的位置(索引),并对Buffer进行切割处理,最终拼接成javascript对象(除了文件),并将文件写入磁盘(临时目录);

formidable的解析步骤

  1. 后端处理请求
    // server.js
    let formy = new formidable.IncomingForm();
    formy
         .on('field', function (field, value) {
           
             console.log(field, value);
         })
         .on('file', function (field, file) {
           
             console.log(field, file);
         })
         .on("end", function () {
           
               res.writeHead(200, {
            "content-type": "application/json" })
               res.end(JSON.stringify({
           
                   code: 0,
                   data: "good",
               }))
           });
    formy.parse(req);
    

你可能感兴趣的:(源码学习,javascript,formdata,源码,nodejs,formidable)