Ключ соответствия и значение разделенной границы
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
и это должно быть добавлено
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)
Объяснение:
Фактическая граница состоит из
Content-Type
"sboundary
стоимость путем добавления\r\n--
и добавление\r\n
к этому. следовательно--QWERTY\r\n
в начале регулярного выражения.Каждая часть в составном HTTP-сообщении имеет заголовок, представляющий собой последовательность непустых строк (
(?:.+\r\n)*
) сразу после границы и заканчивается пустой строкой ((?:.+\r\n)*\r\n
).Первая строка заголовка детали содержит
name="value"
пара, которая определяет имя, которое нас интересует. Это может быть сопоставлено с(?:.+name=\"([^\"]+)\".*\r\n)
, Обратите внимание на первую группу захвата здесь (([^\"]+)
) - это название нашего интереса.После заголовка части у нас есть содержимое части, которое снова представляет собой серию непустых строк (
(?:.+\r\n)*
) с последней строкой не включая\r\n
(принадлежность к следующей границе). Таким образом, последняя строка соответствует.+
(группа без захвата) и все содержимое части((?:.+\r\n)*.+)
, Это также входит в группу захвата, так как нам нужен этот конкретный бит как значение поля.Нам нужно закончить нашу часть с границей
(?=\r\n--QWERTY)
но это должно быть сопоставлено с использованием предпросмотра нулевой длины, чтобы позволить этой границе соответствовать на следующем регулярном выраженииexec()
,
Демонстрация упрощенного Node.js: https://ideone.com/fQN2hB