Ключ соответствия и значение разделенной границы

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)

Объяснение:

  1. Фактическая граница состоит из Content-Type"s boundary стоимость путем добавления \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

Другие вопросы по тегам