Jak przetwarzać dane POST w Node.js?


636

Jak wyodrębnić dane formularza ( form[method="post"]) i przesłane pliki wysłane z POSTmetody HTTP w Node.js ?

Przeczytałem dokumentację, przejrzałem Google i nic nie znalazłem.

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

Czy jest biblioteka lub hack?

Odpowiedzi:


551

Jeśli korzystasz z Express (wysokowydajne, wysokiej klasy projektowanie stron internetowych dla Node.js), możesz to zrobić:

HTML:

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

Klient API:

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

Node.js: (od 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: (dla 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
Funkcjonalność jest w rzeczywistości w module BodyParser w połączeniu, jeśli chcesz użyć punktu wejścia niższego poziomu.
Julian Birch,

14
Jestem zmieszany. W jaki sposób name = "user [email]" odpowiada request.body.email?
sbose

36
Bóg!! Dostaję szału z odczytaniem 3 doumentations w tym samym czasie w tym samym ram: / nodejs.org/api/http.html , senchalabs.org/connect & expressjs.com/guide.html
Salman von Abbas

15
Nie działało to dla mnie, dopóki nie dodałem app.use(express.bodyParser());.
pettys

13
Express jest węzłem tym, co jQuery jest po stronie klienta JS. Za każdym razem, gdy korzystam z pomocy Google dla węzła, dostaję takie kiepskie „użyj ekspresu!” odpowiedzi Czy naprawdę tak trudno jest przeanalizować przesyłane dane, że uzasadnia to zainstalowanie całego środowiska sieciowego?
Shawn Whinnery

710

Możesz użyć querystringmodułu:

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.
        });
    }
}

Teraz, na przykład, jeśli masz inputpole o nazwie age, możesz uzyskać do niego dostęp za pomocą zmiennej post:

console.log(post.age);

8
@ thehehh Hm, to dobra uwaga. Dodanie tego nie powinno być trudne, więc pomijam ten przykład, aby wszystko było proste.
Casey Chu,

72
Rozwój serwera sieciowego node.js jest nękany oprogramowaniem pośredniczącym, które wymaga studiowania go przez wiele godzin, aby zaoszczędzić minut kodowania. Nie mówiąc już o skąpej dokumentacji, którą oferują prawie wszystkie. A twoja aplikacja kończy się na kryteriach innych ludzi, a nie twoich. Plus dowolna liczba problemów z wydajnością.
Juan Lanus,

4
var POST = qs.parse(body); // use POST tylko dla noobów takich jak ja: gdy nazwa wejściowego pola tekstowego to „użytkownik”, Post.userpokaże dane tego pola. np.console.log(Post.user);
Michael Moeller

5
Możesz także użyć readablewywołania zwrotnego zamiast budować dane w ciągu znaków. Po wystrzeleniu ciało jest dostępne przezrequest.read();
Thomasa Fankhausera

4
Zauważ, że req.connection.destroy(); to nie zapobiega wykonaniu wywołań zwrotnych! Na przykład wywołanie zwrotne „on end” zostanie wykonane przy obciętym ciele! Prawdopodobnie nie tego chcesz ...
collimarco

149

Pamiętaj, aby zabić połączenie, jeśli ktoś spróbuje zalać pamięć RAM!

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
Możesz również zwrócić kod błędu HTTP 413 (żądanie jednostki jest zbyt duże)
neoascetic

1
@SSHTo: Nie, to 1 * 10 ^ 6 = 1000000.
thejh

@tq: w tym przypadku POST [nazwa] (np. POST [„foo”]).
thejh

2
var POST = qs.parse(body); // use POST tylko dla noobów: gdy nazwa wejściowego pola tekstowego to „użytkownik”, Post.user wyświetli dane tego pola. np. console.log (Post.user);
Michael Moeller

2
Czy ktoś może mi pomóc, jeśli opublikuję {„Imię”: „Joe”} Dostaję {{„Imię”: „Joe”}: „”} po qs.Parse (POST) ...
Matt Canty

118

Wiele odpowiedzi tutaj nie jest już dobrymi praktykami lub niczego nie wyjaśniam, dlatego to piszę.

Podstawy

Kiedy wywołanie zwrotne http.createServer jest wywoływane, oznacza to, że serwer faktycznie otrzymał wszystkie nagłówki żądania, ale możliwe jest, że dane nie zostały jeszcze odebrane, więc musimy na to poczekać. Obiekt żądania HTTP (instancja http.IncomingMessage) jest w rzeczywistości strumieniem czytelnym . W strumieniach czytelnych za każdym razem, gdy przybywa fragment danych, emitowane jest zdarzenie (zakładając, że zarejestrowałeś wywołanie zwrotne do niego), a po nadejściu wszystkich fragmentów wydarzenie jest emitowane. Oto przykład, w jaki sposób słuchasz wydarzeń: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)

Konwersja buforów na ciągi

Jeśli spróbujesz tego, zauważysz, że fragmenty są buforami . Jeśli nie masz do czynienia z danymi binarnymi i zamiast tego potrzebujesz pracy z ciągami, sugeruję użycie metody request.setEncoding , która powoduje, że strumień emituje ciągi interpretowane z danym kodowaniem i poprawnie obsługuje znaki wielobajtowe.

Buforowanie fragmentów

Teraz prawdopodobnie nie interesuje Cię każdy fragment, więc w tym przypadku prawdopodobnie chcesz go buforować w następujący sposób:

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)

Tutaj używany jest Buffer.concat , który po prostu łączy wszystkie bufory i zwraca jeden duży bufor. Możesz także użyć modułu konkat-stream który robi to samo:

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

Analiza treści

Jeśli próbujesz zaakceptować HTML tworzy przedstawienie POST bez plików lub wręczać jQuery ajax połączeń z domyślnego typu zawartości, a następnie typ zawartości jest application/x-www-form-urlencodedz uft-8kodowaniem. Możesz użyć modułu querystring, aby dokonać serializacji i uzyskać dostęp do właściwości:

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)

Jeśli zamiast tego masz typ JSON, możesz po prostu użyć JSON.parse zamiast qs.parse .

Jeśli masz do czynienia z plikami lub obsługujesz wieloczęściowy typ zawartości, to w takim przypadku powinieneś użyć czegoś takiego jak budzący grozę, który usuwa cały ból związany z radzeniem sobie z tym. Spójrz na moją inną odpowiedź, w której zamieściłem pomocne linki i moduły do ​​treści wieloczęściowych.

Rurociąg

Jeśli nie chcesz analizować zawartości, ale przesłać ją w inne miejsce, na przykład wyślij ją do innego żądania http jako dane lub zapisz w pliku, sugeruję potokowanie raczej przesłanie zamiast buforowania, ponieważ będzie mniej kod, lepiej radzi sobie z przeciwciśnieniem, zajmie mniej pamięci, a w niektórych przypadkach szybciej.

Więc jeśli chcesz zapisać zawartość do pliku:

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

Ograniczanie ilości danych

Jak zauważyły ​​inne odpowiedzi, pamiętaj, że złośliwi klienci mogą wysyłać ci ogromną ilość danych, aby spowodować awarię aplikacji lub zapełnić pamięć, aby zabezpieczyć się przed odrzuceniem żądań, które emitują dane, przekraczają pewien limit. Jeśli nie używasz biblioteki do obsługi przychodzących danych. Sugerowałbym użycie czegoś w rodzaju miernika strumienia, który może przerwać żądanie, jeśli osiągnie określony limit:

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

lub

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

lub

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

Moduły NPM

Chociaż opisałem powyżej, w jaki sposób można używać treści żądania HTTP, do zwykłego buforowania i analizowania zawartości, sugeruję użycie jednego z tych modułów, który jest implementowany samodzielnie, ponieważ prawdopodobnie będą lepiej obsługiwać przypadki brzegowe. W przypadku ekspresu sugeruję użycie parsera ciała . W przypadku koa istnieje podobny moduł .

Jeśli nie używasz frameworka, body jest całkiem dobre.


Dzięki, użyłem twojego kodu i otrzymałem tajemnicze duplikaty wiadomości. Czy to możliwe, że zmienna requestjest ponownie wykorzystywana i request.on('end')wywoływana wielokrotnie? Jak mogę tego uniknąć?
Yan King Yin

Nie wiem, dlaczego nie widzę twojego kodu. Zauważ, że dla każdego żądania request.on('end', ...)będą wywoływane.
Farid Nouri Neshat

Prawdopodobnie nie ma to związku z twoim kodem, robię zdarzenia wysyłane przez serwer i być może spieprzyłem ... Twój kod działa dobrze, w każdym razie dzięki :)
Yan King Yin

Jak wpływa to na wydajność w porównaniu z przetwarzaniem żądania GET bez procedury obsługi „końca”, tj. Bez buforowania fragmentów?
JSON

1
Oto najlepsza odpowiedź na pytanie. 🧐
montrealist

103

Oto bardzo proste opakowanie bez frameworka oparte na innych odpowiedziach i artykułach zamieszczonych tutaj:

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();
    }
}

Przykład użycia:

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);

Czy ta kontrola nie powinna zostać przeniesiona do osobnego oprogramowania pośredniego, aby mogła sprawdzić zbyt duże żądania dla wszystkich żądań post / put
Pavel Nikolov

@PavelNikolov jest to przeznaczone głównie do szybkich i brudnych zadań, w przeciwnym razie lepiej jest użyć Express, tak jak w przypadku przyjętej tutaj odpowiedzi (która prawdopodobnie zajmuje się także zarządzaniem dużymi żądaniami). Możesz je jednak modyfikować i „rozwidlać” według własnych upodobań.
Mahn

Co z metodą .read ()? Czy to nie jest obsługiwane przez moduł http? Na przykład. response.read ()
BT

Hej, po prostu ciekawy - dlaczego umieściłeś ładunek w obiekcie odpowiedzi (response.post) zamiast w obiekcie żądania?
Jotham

@Jotham dobre pytanie ... Nie mam pojęcia, dlaczego nie zauważyłem tego wcześniej, ale nie ma powodu, dla którego powinno to być response.postbardziej logiczne request.post. Zaktualizowałem post.
Mahn

83

Będzie czystsze, jeśli zakodujesz swoje dane w JSON , a następnie wyślesz je do 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
To działało dla mnie. Okazuje się, że inne rozwiązania zwróciły ciąg, który wyglądał jak JSON, ale nie został przeanalizowany. Zamiast qs.parse(), JSON.parse()okazało się, że ciało w coś użyteczny. Przykład:, var post = JSON.parse(body);a następnie uzyskaj dostęp do danych za pomocą post.fieldname. (Morał z tej historii, jeśli jesteś zdezorientowany co do tego, co widzisz, nie zapomnij o typeof!)
wmassingham

12
Cóż, pamiętaj, że musisz spróbować złapać funkcję JSON.parse, ponieważ jeśli chcę zawiesić aplikację, po prostu wyślij ciało z surowym tekstem.
ecarrizo

Powinieneś użyć, request.setEncodingaby to działało poprawnie, w przeciwnym razie może nie obsługiwać poprawnie znaków innych niż ascii.
Farid Nouri Neshat,

37

Dla każdego, kto zastanawia się, jak wykonać to trywialne zadanie bez instalowania frameworka internetowego, udało mi się to połączyć. Produkcja prawie nie jest gotowa, ale wydaje się, że działa.

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);
        })
    }
}

Wreszcie rozwiązanie PEŁNE DZIAŁANIE dla tego dziwnego problemu .. również poprzednia odpowiedź bardzo pomogła zrozumieć, dlaczego w żądaniu nie było żadnych danych, gdy rozpoczyna się oddzwanianie. Wielkie dzięki!
luis-br

3
1) Ta odpowiedź zakłada, że ​​dane są ciągiem. Złe założenie, w ogólnym przypadku. 2) Ta odpowiedź zakłada, że ​​dane docierają w jednym kawałku. W przeciwnym razie podzielenie przez „=” da nieprzewidziany wynik. Złe założenie, w ogólnym przypadku.
Konstantin

@Konstantin W rzeczywistości ta odpowiedź zakłada, że ​​dane są buforem. Spójrz na to. stackoverflow.com/questions/14551194/... Również to. millermedeiros.github.io/mdoc/examples/node_api/doc/…
Shawn Whinnery

16

Możesz użyć body-parser oprogramowania pośredniczącego do analizowania treści Node.js.

Pierwsze ładowanie body-parser

$ npm install body-parser --save

Niektóre przykładowy kod

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);
})

Więcej dokumentacji można znaleźć tutaj



9

Oto, jak możesz to zrobić, jeśli używasz węzła-formidable :

var formidable = require("formidable");

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

Mam problem ze ścieżką, gdy próbuję użyć ścieżki lub ścieżki + nazwy, aby uzyskać dostęp do pliku za pomocą lwip.open (ścieżka lub ścieżka + nazwa pojawia się błąd jako
nieotrzymany

7

Jeśli wolisz używać czystego pliku Node.js, możesz wyodrębnić dane POST, tak jak pokazano poniżej:

// 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) Zainstaluj 'body-parser'z npm.

2) Następnie w pliku app.ts

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

3) następnie musisz napisać

app.use(bodyParser.json())

w module app.ts

4) pamiętaj, że to Ty

app.use(bodyParser.json())

na górze lub przed jakąkolwiek deklaracją modułu.

Dawny:

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

5) Następnie użyj

var postdata = req.body;

5

Jeśli nie chcesz porcji danych razem z dataoddzwanianiem, zawsze możesz użyć readableoddzwaniania w następujący sposób:

// 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
});

Takie podejście modyfikuje przychodzące żądanie, ale zaraz po zakończeniu odpowiedzi zostanie ono wyrzucone, więc nie powinno to stanowić problemu.

Zaawansowanym podejściem byłoby sprawdzenie najpierw wielkości ciała, jeśli boisz się dużych ciał.


Dogodny sposób, aby to zrobić, ale jak „najpierw sprawdzić rozmiar ciała” w sposób, którego nie da się oszukać złośliwym żądaniem?
doug65536,

requestjest normalnym strumieniem node.js, więc możesz sprawdzić request.headersdługość ciała i przerwać żądanie, jeśli to konieczne.
Thomas Fankhauser,

1
@ThomasFankhauser Długość ciała w nagłówku może być niepoprawna lub nawet obecna. Właściwy sposób to zrobić, gdy ciało przybywa i buforujesz je, sprawdzasz rozmiar, aby upewnić się, że nie przekroczy limitu.
Farid Nouri Neshat

4

Można to zrobić na wiele sposobów. Jednak najszybszym sposobem, jaki znam, jest użycie biblioteki Express.js z body-parserem.

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);

Może to działać w przypadku ciągów, ale zamiast tego zmienię bodyParser.urlencoded na bodyParser.json, jeśli dane POST zawierają tablicę JSON.

Więcej informacji: http://www.kompulsa.com/how-to-accept-and-parse-post-requests-in-node-js/


4

Musisz odbierać POSTdane w porcjach za pomocą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)

Należy rozważyć dodanie limitu rozmiaru we wskazanej pozycji, zgodnie z sugestią jh .


Czy jest to bardziej podatne na atak slow-loris?

Nodejs jest mniej podatny na slow-loris niż np. Php - ponieważ nie buduje dużego obiektu sesji wokół każdego połączenia http. Wydaje się jednak, że ten kod nadal może wprowadzać lukę w zabezpieczeniach typu slow-loris. Można temu zapobiec setTimeout, gdy połączenie zakończy połączenie po pewnym czasie, jeśli pełne żądanie nie zostanie odebrane w tym oknie.
Gershom,


3

Jeśli używasz Express.js , zanim będziesz mógł uzyskać dostęp do req.body, musisz dodać oprogramowanie pośrednie bodyParser:

app.use(express.bodyParser());

Następnie możesz poprosić o

req.body.user

Większość oprogramowania pośredniego (takiego jak bodyParser) nie jest już dołączana do Express i musi być instalowana osobno. Zobacz odpowiedź z @ nikodean2 powyżej, aby uzyskać bardziej aktualną odpowiedź
Jeff Collier

app.use (bodyParser ()); działa, ale daje mi przestarzałe czerwone komunikaty o błędach
Chris Allinson

2

A jeśli nie chcesz korzystać z całego frameworka, takiego jak Express, ale potrzebujesz także różnego rodzaju formularzy, w tym przesyłania, formala może być dobrym wyborem.

Jest wymieniony w modułach Node.js


1

Znalazłem film, który wyjaśnia, jak to osiągnąć: https://www.youtube.com/watch?v=nuw48-u3Yrg

Wykorzystuje domyślny moduł „http” wraz z modułami „querystring” i „stringbuilder”. Aplikacja pobiera dwie liczby (używając dwóch pól tekstowych) ze strony internetowej i po przesłaniu zwraca sumę tych dwóch (wraz z utrwaleniem wartości w polach tekstowych). To najlepszy przykład, jaki mogłem znaleźć gdziekolwiek indziej.

Powiązany kod źródłowy:

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

Dla tych, którzy używają surowego binarnego przesyłania POST bez narzutu kodowania, możesz użyć:

klient:

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);

serwer:

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

Możesz użyć ekspresowego oprogramowania pośredniego, które ma teraz wbudowany parser treści. Oznacza to, że wszystko, co musisz zrobić, to:

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)
})

Ten przykład kodu to ES6 z Express 4.16.x


0

możesz wyodrębnić parametr post bez użycia express.

1: nmp install multiparty

2: import wielopartyjny. tak jakvar 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: i FORMULARZ HTML JEST.

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

Mam nadzieję, że to zadziała dla ciebie. Dzięki.


0

Ogranicz rozmiar POST, aby uniknąć zalania aplikacji węzła. Istnieje świetny moduł typu raw-body , odpowiedni zarówno do ekspresowego, jak i łączenia, który może pomóc ograniczyć żądanie według rozmiaru i długości.


0

Jeśli wiąże się to z przesłaniem pliku, przeglądarka zwykle wysyła go jako "multipart/form-data"typ zawartości. Możesz użyć tego w takich przypadkach

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

Odniesienie 1

Odnośnik 2


0

Na takich polach formularza

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

niektóre z powyższych odpowiedzi zakończą się niepowodzeniem, ponieważ obsługują tylko dane płaskie.

Na razie używam odpowiedzi Casey Chu, ale z „qs” zamiast z modułem „querystring”. Jest to również moduł wykorzystywany przez moduł „body-parser” . Więc jeśli chcesz zagnieżdżonych danych, musisz zainstalować qs.

npm install qs --save

Następnie zastąp pierwszy wiersz, np .:

//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

Możesz łatwo wysyłać i otrzymywać odpowiedzi na żądanie POST, używając „Żądania - uproszczonego klienta HTTP” i 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

Musisz użyć bodyParser (), jeśli chcesz, aby dane formularza były dostępne w req.body. body-parser analizuje twoje zapytanie i konwertuje je do formatu, z którego możesz łatwo wyodrębnić odpowiednie informacje, których możesz potrzebować.

Załóżmy na przykład, że masz interfejs rejestracji w interfejsie użytkownika. Wypełniasz go i prosisz serwer o zapisanie gdzieś szczegółów.

Wyodrębnienie nazwy użytkownika i hasła z żądania jest tak proste, jak poniżej, jeśli używasz parsera ciała.

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

var loginDetails = {

username : request.body.username,

password : request.body.password

};

0

JEDEN LINER bez ŚRODKOWEGO OPROGRAMOWANIA
Jeśli publikujesz następujące dane,
'name':'ABC'
możesz je przeanalizować przy użyciu następującego linera ,

require('url').parse(req.url, true).query.name
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.