В этом посте освещается попытка взглянуть на необработанный формат данных, отправленных в теле запроса POST, и способы их анализа. Существуют такие пакеты, как body-parser для Express, которые делают это за нас, поэтому этот пост предназначен только для учебных целей. Я не предлагаю использовать это решение в производстве.
При отправке почтовых запросов на сервер через отправку HTML-формы данные, отправляемые на серверную часть, обычно настраиваются с одним из следующих типов мультимедиа: application / x-www-form-urlencoded, multipart / данные формы или текст / простой. В этом примере я смотрю на application / x-www-form-urlencoded.
Создание нашего сервера
Давайте настроим его, используя приведенный ниже фрагмент:
const http = require('http'); const server = http.createServer((req, res) => { res.end(` <!doctype html> <html> <body> <form action="/" method="post"> <input type="text" name="fname" /><br /> <input type="number" name="age" /><br /> <input type="file" name="photo" /><br /> <button>Save</button> </form> </body> </html> `); }); server.listen(3000);
Это должно открыть страницу по адресу http: // localhost: 3000 с веб-формой:
Заполнение полей и нажатие кнопки «Сохранить» отправит результаты по корневому пути, содержащему поля данных, как и ожидалось. При этом будет использоваться тип носителя по умолчанию application / x-www-form-urlencoded. Это означает, что он создаст строку запроса, используя имена полей в качестве ключей и их данные в качестве значений.
Захват POSTed данных
Чтобы настроить сцену для захвата этих данных, мы должны сначала проверить, что это запрос POST:
const http = require('http'); const server = http.createServer((req, res) => { if (req.method === 'POST') { // Handle post info... } else { res.end(` <!doctype html> <html> <body> <form action="/" method="post"> <input type="text" name="fname" /><br /> <input type="number" name="age" /><br /> <input type="file" name="photo" /><br /> <button>Save</button> </form> </body> </html> `); } }); server.listen(3000);
Учитывая, что запрос, отправленный на серверную часть, является Читаемым потоком, EventEmitter API используется как средство чтения данных. этот поток (нам не нужно импортировать здесь модуль 'событий', поскольку объект запроса расширяет EventEmitter):
... if (req.method === 'POST') { let body = ''; req.on('data', chunk => { body += chunk.toString(); // convert Buffer to string }); req.on('end', () => { console.log(body); res.end('ok'); }); } ...
Заполнение формы и нажатие кнопки «Сохранить» приведет к выходу этой информации на консоль:
fname=Jermaine&age=29&photo=jermaine-photo.png
Каждое поле в форме разделяется символом амперсанда (&), а ключ и значения разделяются символом равенства.
Анализ данных
Чтобы упростить доступ к каждой паре ключ / значение, мы будем использовать встроенный в Node модуль querystring для преобразования данных в объект:
// At the top of the file const { parse } = require('querystring'); ... ... if (req.method === 'POST') { let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', () => { console.log( parse(body) ); res.end('ok'); }); } ...
Результат будет ниже:
{ fname: 'Jermaine', age: '29', photo: 'jermaine-photo.jpg' }
Чтобы немного упорядочить это, давайте создадим служебную функцию, чтобы упростить приведенное выше:
function collectRequestData(request, callback) { const FORM_URLENCODED = 'application/x-www-form-urlencoded'; if(request.headers['content-type'] === FORM_URLENCODED) { let body = ''; request.on('data', chunk => { body += chunk.toString(); }); request.on('end', () => { callback(parse(body)); }); } else { callback(null); } }
Мы будем использовать нашу функцию так:
... if(req.method === 'POST') { collectRequestData(req, result => { console.log(result); res.end(`Parsed data belonging to ${result.fname}`); }); } ...
Заполните форму, и при отправке должно появиться сообщение ниже:
Ниже представлено полное решение:
Ограничения
Вы бы заметили, что при загрузке файла серверной части отправляется только имя файла, а не сам файл. Это ограничение типа носителя application / x-www-form-urlencoded. Использование multipart / form-data отправит необработанный файл вместе с его метаданными. Возможно, в одном из следующих постов мы рассмотрим, как это можно сделать! А пока вот как обрабатывать тело запроса POST в Dart без использования фреймворка.
Я надеюсь, что это открыло глаза на то, как выглядит формат необработанных данных, отправленных в серверную часть, и как мы с этим справимся.
Интересно, что я веду канал YouTube, обучающий подписчиков созданию полнофункциональных приложений с использованием языка Dart и его экосистемы. Подпишитесь сегодня и присоединяйтесь ко мне в этом путешествии.
Как всегда, мы ждем ваших отзывов. Спасибо заранее.