Як обробити дані POST в Node.js?


637

Як витягуєте дані форми ( form[method="post"]) та завантажуєте файли, надіслані POSTметодом HTTP в Node.js ?

Я прочитав документацію, гугл і нічого не знайшов.

function (request, response) {
    //request.post????
}

Є бібліотека чи хак?

Відповіді:


552

Якщо ви використовуєте Express (високоефективна, висококласна веб-розробка для Node.js), ви можете це зробити:

HTML:

<form method="post" action="/">
    <input type="text" name="user[name]">
    <input type="text" name="user[email]">
    <input type="submit" value="Submit">
</form>

API клієнта:

fetch('/', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        user: {
            name: "John",
            email: "john@example.com"
        }
    })
});

Node.js: (оскільки Express v4.16.0)

// Parse URL-encoded bodies (as sent by HTML forms)
app.use(express.urlencoded());

// Parse JSON bodies (as sent by API clients)
app.use(express.json());

// Access the parse results as request.body
app.post('/', function(request, response){
    console.log(request.body.user.name);
    console.log(request.body.user.email);
});

Node.js: (для Express <4.16.0)

const bodyParser = require("body-parser");

/** bodyParser.urlencoded(options)
 * Parses the text as URL encoded data (which is how browsers tend to send form data from regular forms set to POST)
 * and exposes the resulting object (containing the keys and values) on req.body
 */
app.use(bodyParser.urlencoded({
    extended: true
}));

/**bodyParser.json(options)
 * Parses the text as JSON and exposes the resulting object on req.body.
 */
app.use(bodyParser.json());

app.post("/", function (req, res) {
    console.log(req.body.user.name)
});

45
Ця функція фактично знаходиться в модулі BodyParser підключення, якщо ви хочете використовувати нижчу точку входу.
Джуліан Береза

14
Я збентежений. Як name = "user [email]" відповідає request.body.email?
sbose

36
Боже !! мені зле, коли я маю читати 3 дументації одночасно за тією ж основою: / nodejs.org/api/http.html , senchalabs.org/connect & expressjs.com/guide.html
Салман фон Аббас,

15
Це не спрацювало для мене, поки я не додав app.use(express.bodyParser());.
pettys

13
Express полягає в тому, щоб визначити, що таке jQuery для клієнта на JS. Кожен раз, коли я отримую довідку google для вузла, я отримую ці кульгаві "використовувати express!" відповіді. Невже насправді так важко розібрати дані публікації, що це виправдовує встановлення цілої веб-рамки?
Шон Віннірі

710

Ви можете використовувати querystringмодуль:

var qs = require('querystring');

function (request, response) {
    if (request.method == 'POST') {
        var body = '';

        request.on('data', function (data) {
            body += data;

            // Too much POST data, kill the connection!
            // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
            if (body.length > 1e6)
                request.connection.destroy();
        });

        request.on('end', function () {
            var post = qs.parse(body);
            // use post['blah'], etc.
        });
    }
}

Наприклад, якщо у вас є inputполе з ім'ям age, ви можете отримати доступ до нього за допомогою змінної post:

console.log(post.age);

8
@thejh Гм, це хороший момент. Це не повинно бути важко додати, тому я залишу це з прикладу, щоб все було просто.
Кейсі Чу

72
Розробка веб-сервера node.js загрожує середнім програмним забезпеченням, яке вимагає, щоб ви вивчали їх годинами, щоб заощадити хвилин, що варті кодування. Не кажучи вже про мізерну документацію, яку вони пропонують майже всі. І ваша заявка в кінцевому підсумку покладається на критерії інших людей, а не на ваші. Плюс будь-яку кількість питань щодо продуктивності.
Хуан Ланус

4
var POST = qs.parse(body); // use POST лише для ноб, таких як я: коли ім'я текстового поля введення "користувач", Post.userпокаже дані цього поля. наприкладconsole.log(Post.user);
Майкл Моллер

5
Ви також можете використовувати readableзворотний виклик, а не вбудовувати дані в рядок тіла. Як тільки його звільняють, тіло стає доступним черезrequest.read();
Томас Фанкхаузер

4
Зауважте, що req.connection.destroy(); не заважає виконувати зворотні дзвінки! Наприклад, зворотний виклик "в кінці" буде виконаний з усіченим корпусом! Мабуть, це не те, що ти хочеш ...
collimarco

149

Не забудьте перервати з'єднання, якщо хтось намагається залити вашу ОЗУ!

var qs = require('querystring');

function (request, response) {
    if (request.method == 'POST') {
        var body = '';
        request.on('data', function (data) {
            body += data;
            // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
            if (body.length > 1e6) { 
                // FLOOD ATTACK OR FAULTY CLIENT, NUKE REQUEST
                request.connection.destroy();
            }
        });
        request.on('end', function () {

            var POST = qs.parse(body);
            // use POST

        });
    }
}

53
Ви також можете повернути код помилки HTTP 413 (Запит
надлишкової сутності

1
@SSHTЦе: Ні, це 1 * 10 ^ 6 = 1000000.
thejh

@tq: у цьому випадку POST [ім'я] (наприклад, POST ["foo"]).
thejh

2
var POST = qs.parse(body); // use POST лише для нообів: коли назва поля введення тексту "користувач", Post.user покаже дані цього поля. наприклад console.log (Post.user);
Майкл Моллер

2
Чи можу хтось допомогти, якщо я опублікую {'Ім'я': 'Джо'} Я отримаю {{'Ім'я': 'Джо'}: ''} після qs.Parse (POST) ...
Метт Кенті

118

Багато відповідей тут вже не є гарною практикою або нічого не пояснюють, тому я це пишу.

Основи

Коли викликається зворотний виклик http.createServer, це коли сервер фактично отримав усі заголовки для запиту, але можливо, дані ще не отримані, тому нам доведеться чекати. Об'єкт запиту http (екземпляр http.IncomingMessage) - це фактично читабельний потік . У читаних потоках щоразу, коли надходить фрагмент даних, подія випромінюється (якщо припустити, що ви зареєстрували зворотний дзвінок до неї), і коли всі фрагменти надійшли, подія випромінюється. Ось приклад того, як ви слухаєте події:data end

http.createServer((request, response) => {
  console.log('Now we have a http message with headers but no data yet.');
  request.on('data', chunk => {
    console.log('A chunk of data has arrived: ', chunk);
  });
  request.on('end', () => {
    console.log('No more data');
  })
}).listen(8080)

Перетворення буферів у рядки

Якщо ви спробуєте це, ви помітите, що шматки буфери . Якщо ви не маєте справу з бінарними даними та вам потрібно працювати з рядками, я пропоную використовувати метод request.setEncoding, який спричиняє потоки випромінювання рядків, інтерпретовані заданим кодуванням та належним чином обробляють багатобайтові символи.

Буферні шматки

Тепер ви, мабуть, не зацікавлені в кожному фрагменті самостійно, тому в цьому випадку, ймовірно, ви хочете передати його таким чином:

http.createServer((request, response) => {
  const chunks = [];
  request.on('data', chunk => chunks.push(chunk));
  request.on('end', () => {
    const data = Buffer.concat(chunks);
    console.log('Data: ', data);
  })
}).listen(8080)

Тут використовується Buffer.concat , який просто об'єднує всі буфери і повертає один великий буфер. Ви також можете використовувати модуль concat-stream, який робить те саме:

const http = require('http');
const concat = require('concat-stream');
http.createServer((request, response) => {
  concat(request, data => {
    console.log('Data: ', data);
  });
}).listen(8080)

Розбір вмісту

Якщо ви намагаєтеся прийняти HTML-форми подання POST без файлів або передачі jQuery ajax- дзвінків із типом контенту за замовчуванням, то тип вмісту application/x-www-form-urlencodedз uft-8кодуванням. Ви можете використовувати модуль запитів для десеріалізації та доступу до властивостей:

const http = require('http');
const concat = require('concat-stream');
const qs = require('querystring');
http.createServer((request, response) => {
  concat(request, buffer => {
    const data = qs.parse(buffer.toString());
    console.log('Data: ', data);
  });
}).listen(8080)

Якщо ваш тип вмісту замість JSON, ви можете просто використовувати JSON.parse замість qs.parse .

Якщо ви маєте справу з файлами або обробляєте багатоповерховий тип вмісту, то в такому випадку вам слід використовувати щось на зразок грізного, що позбавляє всіх болю від боротьби з ним. Подивіться на цю іншу мою відповідь, де я розмістив корисні посилання та модулі для багаточастинного контенту.

Трубопроводи

Якщо ви не хочете проаналізувати вміст, а скоріше передати його десь в іншому місці, наприклад, надішліть його іншому http-запиту як дані або збережіть у файл, я пропоную передати його замість буферизації, оскільки його буде менше код, краще справляється з тиском, це займе менше пам'яті, а в деяких випадках і швидше.

Отже, якщо ви хочете зберегти вміст у файлі:

 http.createServer((request, response) => {
   request.pipe(fs.createWriteStream('./request'));
 }).listen(8080)

Обмеження кількості даних

Як зазначаються інші відповіді, майте на увазі, що зловмисні клієнти можуть надіслати вам величезну кількість даних, щоб зламати вашу програму або заповнити вашу пам'ять, щоб захистити, щоб ви відмовилися від запитів, які випромінюють дані, пройшли певний ліміт. Якщо ви не використовуєте бібліотеку для обробки вхідних даних. Я б запропонував використовувати щось на зразок потокового метра, який може перервати запит, якщо досягнутий визначений ліміт:

limitedStream = request.pipe(meter(1e7));
limitedStream.on('data', ...);
limitedStream.on('end', ...);

або

request.pipe(meter(1e7)).pipe(createWriteStream(...));

або

concat(request.pipe(meter(1e7)), ...);

NPM-модулі

Хоча я описав вище про те, як можна використовувати тіло запиту HTTP, для простого буферизації та розбору вмісту, я пропоную використовувати один з цих модулів, а не реалізувати самостійно, оскільки вони, ймовірно, краще обробляють крайові випадки. Для експресу пропоную використовувати body-аналізатор . Для коа є аналогічний модуль .

Якщо ви не використовуєте рамку, тіло цілком добре.


Дякую, я використав ваш код і отримав загадкові дублювані повідомлення. Чи може бути, що змінна requestповторно використовується і request.on('end')викликається кілька разів? Як я можу цього уникнути?
Ян Кінг Інь

Я не можу сказати чому, не побачивши ваш код. Зверніть увагу, що для кожного запиту request.on('end', ...)буде викликано.
Фарид Нурі Нешат

Це, мабуть, не пов’язано з вашим кодом, я роблю події, надіслані сервером, і, можливо, його накрутили ... ваш код працює нормально, все одно дякую :)
Ян Кінг Інь

Як це впливає на ефективність у порівнянні з обробкою GET-запиту без кінцевого обробника, тобто без буферизації фрагментів?
JSON

1
Це найкраща відповідь на питання. 🧐
montrealist

103

Ось дуже проста обгортка без рамки на основі інших відповідей та статей, розміщених тут:

var http = require('http');
var querystring = require('querystring');

function processPost(request, response, callback) {
    var queryData = "";
    if(typeof callback !== 'function') return null;

    if(request.method == 'POST') {
        request.on('data', function(data) {
            queryData += data;
            if(queryData.length > 1e6) {
                queryData = "";
                response.writeHead(413, {'Content-Type': 'text/plain'}).end();
                request.connection.destroy();
            }
        });

        request.on('end', function() {
            request.post = querystring.parse(queryData);
            callback();
        });

    } else {
        response.writeHead(405, {'Content-Type': 'text/plain'});
        response.end();
    }
}

Приклад використання:

http.createServer(function(request, response) {
    if(request.method == 'POST') {
        processPost(request, response, function() {
            console.log(request.post);
            // Use request.post here

            response.writeHead(200, "OK", {'Content-Type': 'text/plain'});
            response.end();
        });
    } else {
        response.writeHead(200, "OK", {'Content-Type': 'text/plain'});
        response.end();
    }

}).listen(8000);

Чи не слід цю перевірку переносити на окрему проміжну програму, щоб вона могла перевіряти наявність занадто великих запитів на всіх запитах, що надсилаються / ставлять
Павло Ніколов

@PavelNikolov це в основному призначено для швидких і брудних завдань, інакше, мабуть, краще використовувати Express, як рекомендується тут прийнята відповідь (яка, ймовірно, піклується і про управління великими запитами). Не соромтесь змінювати та «розкладати» його на свій смак.
Ман

Що з методом .read ()? Це не підтримується модулем http? Напр. response.read ()
BT

Гей, просто цікаво - чому ви розмістили корисне навантаження в об’єкт відповіді (response.post), а не в об'єкт запиту?
Джотем

@ Джотхем добре запитання ... Я поняття не маю, чому я не помітив цього раніше, але немає причини, чому це має бути, response.postа не більш логічним request.post. Я оновив публікацію.
Ман

83

Це буде чистіше, якщо ви кодуєте свої дані в JSON , а потім надсилаєте їх до Node.js.

function (req, res) {
    if (req.method == 'POST') {
        var jsonString = '';

        req.on('data', function (data) {
            jsonString += data;
        });

        req.on('end', function () {
            console.log(JSON.parse(jsonString));
        });
    }
}

1
Це те, що працювало для мене. Повороти з інших рішень повертається рядок , яка виглядала як JSON , але не був розібраний. Замість того qs.parse(), JSON.parse()перевернули тіло будь-що - то придатні до вживання. Приклад:, var post = JSON.parse(body);потім перейдіть до даних за допомогою post.fieldname. (Мораль історії, якщо вас бентежить те, що ви бачите, не забувайте typeof!)
wmassingham

12
Ну просто пам’ятайте, що ви повинні спробувати зафіксувати функцію JSON.parse, тому що якщо я хочу зірвати вашу програму, я просто надішліть тіло із сирим текстом.
ecarrizo

Вам слід скористатися request.setEncodingдля правильної роботи, інакше вона не може належним чином обробляти символи, що не входять до списку.
Фарид Нурі Нешат

37

Для тих, хто цікавиться, як зробити це тривіальне завдання, не встановлюючи веб-рамки, мені вдалося зірвати це разом. Навряд чи готове виробництво, але, здається, працює.

function handler(req, res) {
    var POST = {};
    if (req.method == 'POST') {
        req.on('data', function(data) {
            data = data.toString();
            data = data.split('&');
            for (var i = 0; i < data.length; i++) {
                var _data = data[i].split("=");
                POST[_data[0]] = _data[1];
            }
            console.log(POST);
        })
    }
}

Нарешті, ПОЛЬНЕ РОБОЧЕ вирішення цієї дивної проблеми. Так само попередня відповідь дуже допомогла зрозуміти, чому в запиті не було ніяких даних, коли починається зворотний виклик. Дякую!
luis-br

3
1) Ця відповідь передбачає, що дані є рядком. Погане припущення, в загальному випадку. 2) Ця відповідь передбачає, що дані надходять за один шматок. В іншому випадку розщеплення на '=' дасть непередбачуваний результат. Погане припущення, в загальному випадку.
Костянтин

@Konstantin Насправді ця відповідь передбачає, що дані є буфером. Заціни. stackoverflow.com/questions/14551194/… Також це. millermedeiros.github.io/mdoc/examples/node_api/doc/…
Shawn Whinnery

16

Ви можете використовувати body-parserпроміжне програмне забезпечення для розбору тіла Node.js.

Перше навантаження body-parser

$ npm install body-parser --save

Деякі приклади коду

var express = require('express')
var bodyParser = require('body-parser')

var app = express()

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())


app.use(function (req, res) {
  var post_data = req.body;
  console.log(post_data);
})

Більше документації можна знайти тут



9

Ось як це можна зробити, якщо ви використовуєте формат, який можна формувати :

var formidable = require("formidable");

var form = new formidable.IncomingForm();
form.parse(request, function (err, fields) {
    console.log(fields.parameter1);
    console.log(fields.parameter2);
    // ...
});

У мене виникають проблеми з контуром, коли я намагаюся використовувати шлях або шлях + ім'я для доступу до файлу з lwip.open (шлях або шлях + ім'я, я отримую помилку як непомітне зображення.
Lion789,

7

Якщо ви віддаєте перевагу використовувати чистий Node.js, ви можете витягнути дані POST, як показано нижче:

// Dependencies
const StringDecoder = require('string_decoder').StringDecoder;
const http = require('http');

// Instantiate the HTTP server.
const httpServer = http.createServer((request, response) => {
  // Get the payload, if any.
  const decoder = new StringDecoder('utf-8');
  let payload = '';

  request.on('data', (data) => {
    payload += decoder.write(data);
  });

  request.on('end', () => {
    payload += decoder.end();

    // Parse payload to object.
    payload = JSON.parse(payload);

    // Do smoething with the payload....
  });
};

// Start the HTTP server.
const port = 3000;
httpServer.listen(port, () => {
  console.log(`The server is listening on port ${port}`);
});


6

1) Встановити 'body-parser' з npm.

2) Потім у ваших app.ts

var bodyParser = require('body-parser');

3) тоді потрібно писати

app.use(bodyParser.json())

у додатках модулі

4) майте на увазі, що ви включаєте

app.use(bodyParser.json())

вгорі або перед будь-яким оголошенням модуля.

Наприклад:

app.use(bodyParser.json())
app.use('/user',user);

5) Потім використовуйте

var postdata = req.body;

5

Якщо ви не хочете обробляти свої дані разом із dataзворотним дзвоном, ви завжди можете використовувати readableзворотний виклик так:

// Read Body when Available
request.on("readable", function(){
  request.body = '';
  while (null !== (request.body += request.read())){}
});

// Do something with it
request.on("end", function(){
  request.body //-> POST Parameters as String
});

Цей підхід змінює вхідний запит, але як тільки ви закінчите свою відповідь, запит буде зібраний сміттям, так що це не повинно бути проблемою.

Передовим підходом було б спочатку перевірити розмір тіла, якщо ти боїшся величезних тіл.


Зручний спосіб це зробити, але як "спочатку перевірити розмір тіла" таким чином, щоб не обдурити шкідливий запит?
doug65536

requestє нормальним потоком node.js, тому ви можете перевірити request.headersдовжину тіла та скасувати запит, якщо це необхідно.
Thomas Fankhauser

1
@ThomasFankhauser Довжина тіла в заголовку може бути не правильним значенням або навіть присутнім. Правильний спосіб зробити це, коли тіло прибуває і ви буферизуєте його, ви перевіряєте розмір, щоб переконатися, що він не перейшов межу.
Фарид Нурі Нешат

4

Існує кілька способів зробити це. Однак найшвидший спосіб, який я знаю, - це використовувати бібліотеку Express.js з аналізатором тіла.

var express = require("express");
var bodyParser = require("body-parser");
var app = express();

app.use(bodyParser.urlencoded({extended : true}));

app.post("/pathpostdataissentto", function(request, response) {
  console.log(request.body);
  //Or
  console.log(request.body.fieldName);
});

app.listen(8080);

Це може працювати для рядків, але я замінюю bodyParser.urlencoded на bodyParser.json, якщо дані POST містять масив JSON.

Більше інформації: http://www.kompulsa.com/how-to-accept-and-parse-post-requests-in-node-js/


4

POSTДані потрібно отримувати за допомогою шматочківrequest.on('data', function(chunk) {...})

const http = require('http');

http.createServer((req, res) => {
    if (req.method == 'POST') {
        whole = ''
        req.on('data', (chunk) => {
            # consider adding size limit here
            whole += chunk.toString()
        })

        req.on('end', () => {
            console.log(whole)
            res.writeHead(200, 'OK', {'Content-Type': 'text/html'})
            res.end('Data received.')
        })
    }
}).listen(8080)

Вам слід розглянути можливість додавання обмеження розміру у вказаній позиції, як запропоновано thejh .


Чи більше це сприйнятливо до нападу повільних лорісів?

Nodejs менш сприйнятливий до лорі-лорісу, ніж, наприклад, php - тому що він не створює великий об'єкт сеансу навколо кожного http-з'єднання. Однак, схоже, цей код все ще може ввести вразливість повільних лорісів. Цього можна запобігти, setTimeoutякщо закінчується з'єднання через певний проміжок часу, якщо повний запит не буде отриманий у цьому вікні.
Гершом


3

Якщо ви використовуєте Express.js , перш ніж отримати доступ до req.body, потрібно додати проміжне програмне забезпечення bodyParser:

app.use(express.bodyParser());

Тоді ви можете попросити

req.body.user

Більшість проміжних програм (як bodyParser) більше не входить у пакет Express та має встановлюватися окремо. Дивіться відповідь від @ nikodean2 вище для більш актуальної відповіді
Джефф Коллер,

app.use (bodyParser ()); працює, але видає мені повідомлення про помилки червоного знецінення
Кріс Алінсон

2

І якщо ви не хочете використовувати весь фреймворк, як Express, але вам також потрібні різні види форм, включаючи завантаження, то формалін може бути хорошим вибором.

Він вказаний у модулях Node.js


1

Я знайшов відео, в якому пояснюється, як цього досягти: https://www.youtube.com/watch?v=nuw48-u3Yrg

Він використовує модуль "http" за замовчуванням разом з модулями "querystring" та "stringbuilder". Додаток бере два числа (використовуючи два текстових поля) з веб-сторінки та після надсилання повертає суму цих двох (разом із збереженням значень у текстових полях). Це найкращий приклад, який я міг знайти деінде.

Пов'язаний вихідний код:

var http = require("http");
var qs = require("querystring");
var StringBuilder = require("stringbuilder");

var port = 9000;

function getCalcHtml(req, resp, data) {
    var sb = new StringBuilder({ newline: "\r\n" });
    sb.appendLine("<html>");
    sb.appendLine(" <body>");
    sb.appendLine("     <form method='post'>");
    sb.appendLine("         <table>");
    sb.appendLine("             <tr>");
    sb.appendLine("                 <td>Enter First No: </td>");

    if (data && data.txtFirstNo) {
        sb.appendLine("                 <td><input type='text' id='txtFirstNo' name='txtFirstNo' value='{0}'/></td>", data.txtFirstNo);
    }
    else {
        sb.appendLine("                 <td><input type='text' id='txtFirstNo' name='txtFirstNo' /></td>");
    }

    sb.appendLine("             </tr>");
    sb.appendLine("             <tr>");
    sb.appendLine("                 <td>Enter Second No: </td>");

    if (data && data.txtSecondNo) {
        sb.appendLine("                 <td><input type='text' id='txtSecondNo' name='txtSecondNo' value='{0}'/></td>", data.txtSecondNo);
    }
    else {
        sb.appendLine("                 <td><input type='text' id='txtSecondNo' name='txtSecondNo' /></td>");
    }

    sb.appendLine("             </tr>");
    sb.appendLine("             <tr>");
    sb.appendLine("                 <td><input type='submit' value='Calculate' /></td>");
    sb.appendLine("             </tr>");

    if (data && data.txtFirstNo && data.txtSecondNo) {
        var sum = parseInt(data.txtFirstNo) + parseInt(data.txtSecondNo);
        sb.appendLine("             <tr>");
        sb.appendLine("                 <td>Sum: {0}</td>", sum);
        sb.appendLine("             </tr>");
    }

    sb.appendLine("         </table>");
    sb.appendLine("     </form>")
    sb.appendLine(" </body>");
    sb.appendLine("</html>");
    sb.build(function (err, result) {
        resp.write(result);
        resp.end();
    });
}

function getCalcForm(req, resp, data) {
    resp.writeHead(200, { "Content-Type": "text/html" });
    getCalcHtml(req, resp, data);
}

function getHome(req, resp) {
    resp.writeHead(200, { "Content-Type": "text/html" });
    resp.write("<html><html><head><title>Home</title></head><body>Want to some calculation? Click <a href='/calc'>here</a></body></html>");
    resp.end();
}

function get404(req, resp) {
    resp.writeHead(404, "Resource Not Found", { "Content-Type": "text/html" });
    resp.write("<html><html><head><title>404</title></head><body>404: Resource not found. Go to <a href='/'>Home</a></body></html>");
    resp.end();
}

function get405(req, resp) {
    resp.writeHead(405, "Method not supported", { "Content-Type": "text/html" });
    resp.write("<html><html><head><title>405</title></head><body>405: Method not supported</body></html>");
    resp.end();
}

http.createServer(function (req, resp) {
    switch (req.method) {
        case "GET":
            if (req.url === "/") {
                getHome(req, resp);
            }
            else if (req.url === "/calc") {
                getCalcForm(req, resp);
            }
            else {
                get404(req, resp);
            }
            break;
        case "POST":
            if (req.url === "/calc") {
                var reqBody = '';
                req.on('data', function (data) {
                    reqBody += data;
                    if (reqBody.length > 1e7) { //10MB
                        resp.writeHead(413, 'Request Entity Too Large', { 'Content-Type': 'text/html' });
                        resp.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
                    }
                });
                req.on('end', function () {
                    var formData = qs.parse(reqBody);
                    getCalcForm(req, resp, formData);
                });
            }
            else {
                get404(req, resp);
            }
            break;
        default:
            get405(req, resp);
            break;
    }
}).listen(port);

1

Для тих, хто використовує необроблене бінарне завантаження POST без кодування накладних витрат, можна використовувати:

клієнт:

var xhr = new XMLHttpRequest();
xhr.open("POST", "/api/upload", true);
var blob = new Uint8Array([65,72,79,74]); // or e.g. recorder.getBlob()
xhr.send(blob);

сервер:

var express = require('express');
var router = express.Router();
var fs = require('fs');

router.use (function(req, res, next) {
  var data='';
  req.setEncoding('binary');
  req.on('data', function(chunk) {
    data += chunk;
  });

  req.on('end', function() {
    req.body = data;
    next();
  });
});

router.post('/api/upload', function(req, res, next) {
  fs.writeFile("binaryFile.png", req.body, 'binary', function(err) {
    res.send("Binary POST successful!");
  });
});

1

Ви можете використовувати експрес- проміжне програмне забезпечення, в яке зараз вбудований аналізатор тіла. Це означає, що вам потрібно:

import express from 'express'

const app = express()

app.use(express.json())

app.post('/thing', (req, res) => {
  console.log(req.body) // <-- this will access the body of the post
  res.sendStatus(200)
})

Цей приклад коду - ES6 з Express 4.16.x


0

ви можете вилучити параметр публікації, не використовуючи express.

1: nmp install multiparty

2: імпорт багатопартійних. якvar multiparty = require('multiparty');

3: `

if(req.method ==='POST'){
   var form = new multiparty.Form();
   form.parse(req, function(err, fields, files) {
      console.log(fields['userfile1'][0]);
    });
    }

4: і HTML-ФОРМА Є.

<form method=POST enctype=multipart/form-data>
<input type=text name=userfile1><br>
<input type=submit>
</form>

Я сподіваюся, що це спрацює для вас. Дякую.


0

Обмежте розмір POST, щоб уникнути затоплення додатка на вузлі. Існує чудовий модуль сировини , який підходить як для швидкої, так і для з'єднання, що допоможе вам обмежити запит за розміром і довжиною.


0

Якщо це стосується завантаження файлу, браузер зазвичай надсилає його як "multipart/form-data"тип вмісту. Ви можете використовувати це в таких випадках

var multipart = require('multipart');
multipart.parse(req)

Довідка 1

Довідка 2


0

На таких формах поля

   <input type="text" name="user[name]" value="MyName">
   <input type="text" name="user[email]" value="myemail@somewherefarfar.com">

деякі з вищезазначених відповідей не зможуть, оскільки вони підтримують лише плоскі дані.

Наразі я використовую відповідь Кейсі Чу, але з "qs" замість модуля "querystring". Це і модуль «тіло-аналізатор» . Тож якщо ви хочете вкладені дані, ви повинні встановити qs.

npm install qs --save

Потім замініть перший рядок, як:

//var qs = require('querystring');
var qs = require('qs'); 

function (request, response) {
    if (request.method == 'POST') {
        var body = '';

        request.on('data', function (data) {
            body += data;

            // Too much POST data, kill the connection!
            // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
            if (body.length > 1e6)
                request.connection.destroy();
        });

        request.on('end', function () {
            var post = qs.parse(body);
            console.log(post.user.name); // should work
            // use post['blah'], etc.
        });
    }
}

0

Ви можете легко надіслати та отримати відповідь на запит POST, скориставшись "Запит - спрощений клієнт HTTP" та Javascript Promise.

var request = require('request');

function getData() {
    var options = {
        url: 'https://example.com',
        headers: {
            'Content-Type': 'application/json'
        }
    };

    return new Promise(function (resolve, reject) {
        var responseData;
        var req = request.post(options, (err, res, body) => {
            if (err) {
                console.log(err);
                reject(err);
            } else {
                console.log("Responce Data", JSON.parse(body));
                responseData = body;
                resolve(responseData);
            }
        });
    });
}

0

Вам потрібно використовувати bodyParser (), якщо ви хочете, щоб дані форми були доступні у req.body. body-parser аналізує ваш запит і перетворює його у формат, з якого ви можете легко отримати відповідну інформацію, яка вам може знадобитися.

Наприклад, припустімо, що у вас на кордоні форма реєстрації. Ви заповнюєте його та просите сервер десь зберегти дані.

Вилучення імені користувача та пароля з вашого запиту відбувається так само просто, як нижче, якщо ви використовуєте body-parser.

…………………………………………………….

var loginDetails = {

username : request.body.username,

password : request.body.password

};

0

ОДИН ЛІНЕР без ПЕРЕГЛЯДУВАННЯ
Якщо ви публікуєте наступні дані,
'name':'ABC'
тоді ви можете їх проаналізувати за допомогою наступного вкладиша,

require('url').parse(req.url, true).query.name
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.