【问题标题】:Match key and value of splitted Boundary匹配分割边界的键和值
【发布时间】:2017-10-27 09:55:52
【问题描述】:
request.on('end', function () {
   if (request.headers.hasOwnProperty('content-type') && request.headers['content-type'].indexOf('boundary=') > -1) {
       var parts = request.headers['content-type'].split('boundary=');
       var boundary = parts[1];
       var splitBody = requestBody.split(boundary);

       console.log(splitBody);
       res.writeHead(200, { "Content-Type": "application/json" });
       res.write(JSON.stringify({ formFields: splitBody }));
   }
   else {
       //bad request
       res.writeHead(400, { "Content-Type": "text/paint" });
       res.write("missing boundary in content-type ");
       }
});

所以我得到了这个(console.log):

[ '--',
'\r\nContent-Disposition: form-data; name="image"\r\n\r\n/ap.jpg\r\n--',
'\r\nContent-Disposition: form-data; name="name"\r\n\r\nsmth\r\n--',
'--\r\n' ]

所以基本上我想做的是遍历 splitBody 并匹配键和值并将其添加到字段数组中。最好的方法是什么?

所以基本上不是这样:

'\r\nContent-Disposition: form-data; name="image"\r\n\r\n/ap.jpg\r\n--',

应该是这样的:

image=ap.jpg

应该添加

【问题讨论】:

  • 显示想要的结果
  • @RomanPerekhrest 查看编辑
  • @RomanPerekhrest 有什么想法吗?
  • 我想,应该有一些东西(内置)可以预先从 requestBody 中删除换行符

标签: node.js regex split match form-fields


【解决方案1】:

如果您需要将内容部分名称和内容提取为一对数组,仅按边界拆分是不够的。您需要详细说明一个正则表达式来匹配和捕获名称和内容,并迭代槽匹配以提取这些对:

...........................
var boundary = parts[1];
var re = new RegExp("--" + boundary + "\r\n(?:.+name=\"([^\"]+)\".*\r\n)(?:.+\r\n)*\r\n" 
    + "((?:.+\r\n)*.+)(?=\r\n--" + boundary + ")", "g");
var match = re.exec(requestBody);
var fields = [];
while (match) {
    var field = {};
    field[match[1]] = match[2];
    fields.push(field);
    match = re.exec(requestBody);
}
console.log(JSON.stringify({ formFields: fields }))
res.writeHead(200, { "Content-Type": "application/json" });
res.write(JSON.stringify({ formFields: fields }));
...........................

为了简单起见,我假设为boundary === "QWERTY" 来解释正则表达式。在这种情况下,正则表达式是:

--QWERTY\r\n(?:.+name="([^"]+)".*\r\n)(?:.+\r\n)*\r\n((?:.+\r\n)*(?:.+))(?=\r\n--QWERTY)

解释:

  1. 实际边界由Content-Typeboundary 值组成,方法是在\r\n-- 前面加上\r\n。因此--QWERTY\r\n 在正则表达式的开头。

  2. 多部分 HTTP 消息中的每个部分都有一个标头,它是一系列紧跟边界并以空字符串 ((?:.+\r\n)*\r\n) 结尾的非空字符串 ((?:.+\r\n)*)。

  3. 部件标题的第一行包含name="value" 对,它定义了我们感兴趣的名称。这可以与(?:.+name=\"([^\"]+)\".*\r\n) 匹配。注意这里的第一个捕获组 (([^\"]+)) - 这是我们感兴趣的名称。

  4. 在部分标题之后,我们得到了部分内容,这又是一系列非空行((?:.+\r\n)*),最后一行不包括\r\n(属于下一个边界)。所以最后一行匹配.+(非捕获组),整个部分内容为((?:.+\r\n)*.+)。这也在捕获组中,因为我们需要这个特定的位作为字段值。

  5. 我们需要以边界 (?=\r\n--QWERTY) 结束我们的部分,但它应该使用零长度前瞻来匹配,以让该边界在下一个正则表达式 exec() 处匹配。

简化的 Node.js 演示:https://ideone.com/fQN2hB

【讨论】:

    猜你喜欢
    • 2018-09-06
    • 2019-04-20
    • 2021-02-09
    • 1970-01-01
    • 2017-07-11
    • 2017-12-20
    • 1970-01-01
    • 1970-01-01
    • 2019-01-23
    相关资源
    最近更新 更多