Bagaimana proses POSTING data di Node.js?

Bagaimana anda mengekstrak bentuk data (form[method="post"]) dan upload file yang dikirim dari HTTP POST metode dalam Node.js?

I'telah membaca dokumentasi, cari di google dan menemukan apa-apa.

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

Ada perpustakaan atau hack?

Anda dapat menggunakan querystring modul:

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

Sekarang, misalnya, jika anda memiliki sebuah input field dengan nama usia, anda bisa mengaksesnya menggunakan variabel post:

console.log(post.age);
Komentar (21)
Larutan

Jika anda menggunakan Express (high-performance, high-kelas pengembangan web untuk Node.js), anda dapat melakukan ini:

HTML:


    <input type="text" name="user[name]">
    <input type="text" name="user[email]">
    <input type="submit" value="Submit">

Klien API:

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

Node.js: (sejak 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: (untuk 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)
});
Komentar (28)

Pastikan untuk membunuh koneksi jika seseorang mencoba untuk banjir RAM anda!

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

        });
    }
}
Komentar (8)

Berikut ini's sangat sederhana tanpa framework wrapper berdasarkan jawaban yang lain dan artikel yang diposting di sini:

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

Contoh penggunaan:

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);
Komentar (6)

Banyak dari jawaban berikut yang tidak praktik-praktik yang baik lagi atau don't menjelaskan apa-apa, sehingga's mengapa saya'm menulis ini.

Dasar-dasar

Ketika balik dari http.createServer disebut, adalah ketika server telah benar-benar menerima semua header permintaan, tapi itu's mungkin bahwa data belum diterima, jadi kita harus menunggu untuk itu. The http request objek(http.IncomingMessage contoh) adalah benar-benar dibaca stream. Di readable stream setiap kali sepotong data tiba, sebuah data acara dipancarkan(dengan asumsi anda telah terdaftar callback untuk itu) dan ketika semua potongan telah tiba sebuah akhir acara yang dipancarkan. Berikut ini's contoh tentang bagaimana anda mendengarkan acara:

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)

Mengkonversi Buffer String

Jika anda mencoba ini, anda akan melihat potongan-potongan yang buffer. Jika anda tidak berurusan dengan data biner dan perlu untuk bekerja dengan string bukannya saya sarankan menggunakan request.setEncoding metode yang menyebabkan aliran memancarkan string ditafsirkan dengan mengingat encoding dan menangani multi-byte karakter dengan benar.

Buffering Potongan

Sekarang anda mungkin tidak tertarik dalam setiap chunk oleh itu's sendiri, jadi dalam hal ini mungkin anda ingin buffer seperti ini:

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)

Di Sini Buffer.concat digunakan, yang hanya merangkai semua buffer dan kembali satu penyangga. Anda juga dapat menggunakan concat-streaming modul yang tidak sama:

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

Parsing Konten

Jika anda mencoba untuk menerima bentuk HTML PASCA pengajuan dengan tidak ada file atau menyerahkan jQuery ajax panggilan dengan default tipe konten, maka konten jenis adalah application/x-www-form-urlencoded dengan uft-8 encoding. Anda dapat menggunakan querystring modul untuk de-cerita bersambung itu dan mengakses properties:

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)

Jika konten anda adalah tipe JSON sebaliknya, anda hanya dapat menggunakan JSON.parse bukan qs.parse.

Jika anda berurusan dengan file atau penanganan multipart jenis konten, maka dalam hal ini, anda harus menggunakan sesuatu seperti yang tangguh yang menghilangkan semua rasa sakit dari berurusan dengan itu. Silahkan lihat di ini jawaban lain saya di mana saya telah diposting link bermanfaat dan modul untuk multipart konten.

Pipa

Jika anda don't ingin mengurai isi melainkan menyebarkannya ke tempat lain, misalnya mengirim ke yang lain permintaan http sebagai data atau menyimpan ke file saya sarankan piping daripada buffering itu, seperti'll be kode kurang, menangani tekanan balik yang lebih baik, it'll mengambil sedikit memori dan dalam beberapa kasus lebih cepat.

Jadi jika anda ingin menyimpan konten ke file:

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

Membatasi Jumlah Data

Sebagai jawaban lain telah mencatat menjaga dalam pikiran saya bahwa klien berbahaya mungkin mengirimkan sejumlah besar data crash aplikasi atau mengisi memori anda sehingga untuk melindungi pastikan anda drop permintaan yang memancarkan data yang melewati batas tertentu. Jika anda don't menggunakan perpustakaan untuk menangani data yang masuk. Saya akan menyarankan menggunakan sesuatu seperti stream-meter yang dapat membatalkan permintaan jika mencapai batas yang ditentukan:

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

atau

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

atau

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

NPM Modul

Sementara aku yang dijelaskan di atas pada bagaimana anda dapat menggunakan HTTP request tubuh, hanya untuk buffering dan parsing isi, saya menyarankan menggunakan salah satu dari modul ini agak menerapkan pada anda sendiri karena mereka mungkin akan menangani kasus tepi yang lebih baik. Untuk mengekspresikan saya sarankan menggunakan body-parser. Untuk koa, ada's mirip modul.

Jika anda don't menggunakan framework, tubuh cukup baik.

Komentar (6)

Itu akan lebih bersih jika anda encode data anda untuk JSON, kemudian mengirimkannya ke 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));
        });
    }
}
Komentar (3)

Bagi siapa saja yang bertanya-tanya bagaimana untuk melakukan hal ini sepele tugas tanpa menginstal framework web saya berhasil celepuk ini bersama-sama. Hampir siap produksi tapi tampaknya bekerja.

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

Anda dapat menggunakan body-parser, yang Node.js tubuh parsing middleware.

Beban pertama body-parser

$ npm install body-parser --save

Beberapa contoh kode

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

Dokumentasi lebih lanjut dapat ditemukan di sini

Komentar (0)

Referensi: https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/

let body = [];
request.on('data', (chunk) => {
  body.push(chunk);
}).on('end', () => {
  body = Buffer.concat(body).toString();
  // at this point, `body` has the entire request body stored in it as a string
});
Komentar (0)

Berikut adalah bagaimana anda bisa melakukannya jika anda menggunakan node-tangguh:

var formidable = require("formidable");

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

Jika anda memilih untuk menggunakan murni Node.js maka anda mungkin ekstrak POSTING data seperti ditunjukkan di bawah ini:

// 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}`);
});
Komentar (0)
  1. Install &#39;body-parser&#39; dari npm.

  2. Maka anda aplikasi.ts

var bodyParser = require('body-parser');
  1. kemudian anda perlu untuk menulis
app.use(bodyParser.json())

di app.ts modul

  1. perlu diingat bahwa anda termasuk
app.use(bodyParser.json())

di atas atau sebelum modul deklarasi.

Ex:

app.use(bodyParser.json())
app.use('/user',user);
  1. Kemudian menggunakan
var postdata = req.body;
Komentar (0)

Jika anda don't ingin chunk data anda bersama-sama dengan data callback anda dapat selalu menggunakan dibaca callback seperti ini:

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

Pendekatan ini memodifikasi permintaan yang masuk, tetapi segera setelah anda selesai respon permintaan akan menjadi sampah yang dikumpulkan, sehingga seharusnya tidak menjadi masalah.

Lanjutan pendekatan yang akan memeriksa ukuran tubuh pertama, jika anda're takut besar tubuh.

Komentar (3)

Anda perlu untuk menerima POST data dalam potongan menggunakan permintaan.pada(&#39;data&#39;, fungsi(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)

Anda harus mempertimbangkan menambahkan batas ukuran pada bagian yang ditunjukkan posisi sebagai thejh menyarankan.

Komentar (2)

Ada beberapa cara untuk melakukannya. Namun, cara tercepat yang saya tahu adalah dengan menggunakan Express.js perpustakaan dengan body-parser.

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

Yang dapat bekerja untuk string, tapi saya akan mengubah bodyParser.urlencoded untuk bodyParser.json sebaliknya jika POSTING berisi data JSON array.

Info lebih lanjut: http://www.kompulsa.com/how-to-accept-and-parse-post-requests-in-node-js/

Komentar (0)

Jika anda menggunakan Express.js, sebelum anda dapat mengakses req.tubuh, anda harus menambahkan middleware bodyParser:

app.use(express.bodyParser());

Kemudian anda dapat meminta

req.body.user
Komentar (2)

Dan jika anda don't ingin menggunakan seluruh kerangka seperti Express, tapi anda juga memerlukan berbagai macam bentuk, termasuk upload, kemudian engkau berjanji mungkin menjadi pilihan yang baik.

Hal ini tercantum dalam Node.js modul

Komentar (0)

Express v4.17.0

app.use(express.urlencoded( {extended: true} ))
Komentar (0)

Saya menemukan sebuah video yang menjelaskan tentang cara untuk mencapai hal ini: https://www.youtube.com/watch?v=nuw48-u3Yrg

Menggunakan default "http" modul bersama-sama dengan "querystring" dan "stringbuilder" modul. Aplikasi ini mengambil dua angka (menggunakan dua kotak teks) dari suatu halaman web dan setelah submit, kembali jumlah dari dua (bersama dengan bertahan pada nilai-nilai di textbox). Ini adalah contoh terbaik yang bisa saya temukan di tempat lain.

Terkait source code:

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("");
    sb.appendLine(" ");
    sb.appendLine("     ");
    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("     ")
    sb.appendLine(" ");
    sb.appendLine("");
    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("HomeWant to some calculation? Click <a href='/calc'>here</a>");
    resp.end();
}

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

function get405(req, resp) {
    resp.writeHead(405, "Method not supported", { "Content-Type": "text/html" });
    resp.write("405405: Method not supported");
    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('413413: Request Entity Too Large');
                    }
                });
                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);
Komentar (0)

Bagi mereka yang menggunakan raw binary POSTING tanggal tanpa encoding overhead yang dapat anda gunakan:

klien:

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

server:

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!");
  });
});
Komentar (0)