Làm cách nào để xử lý dữ liệu POST trong Node.js?


637

Làm cách nào để bạn trích xuất dữ liệu biểu mẫu ( form[method="post"]) và tải lên tệp được gửi từ POSTphương thức HTTP trong Node.js ?

Tôi đã đọc tài liệu, googled và không tìm thấy gì.

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

Có thư viện hay hack không?

Câu trả lời:


552

Nếu bạn sử dụng Express (phát triển web cao cấp, hiệu suất cao cho Node.js), bạn có thể làm điều này:

HTML:

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

Máy khách API:

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

Node.js: (kể từ 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: (dành cho 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
Chức năng thực sự nằm trong mô-đun BodyParser trong kết nối, nếu bạn muốn sử dụng điểm vào cấp thấp hơn.
Julian Birch

14
Tôi bối rối. Tên = "người dùng [email]" tương ứng với request.body.email như thế nào?
sbose

36
Chúa Trời!! Tôi đang phát điên khi phải đọc 3 lần nhân đôi cùng một lúc cho cùng một khung: / nodejs.org/api/http.html , senchalabs.org/connect & expressjs.com/guide.html
Salman von Abbas

15
Điều này đã không làm việc cho tôi cho đến khi tôi thêm app.use(express.bodyParser());.
pettys

13
Express là để nút jQuery là gì đối với JS phía máy khách. Mỗi lần tôi google trợ giúp cho nút tôi lại nhận được những lời khập khiễng "sử dụng express!" câu trả lời. Có thực sự rất khó để phân tích dữ liệu bài đăng mà nó biện minh cho việc cài đặt toàn bộ khung web?
Shawn Whinnery

710

Bạn có thể sử dụng querystringmô-đun:

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

Bây giờ, ví dụ, nếu bạn có một inputtrường có tên age, bạn có thể truy cập nó bằng biến post:

console.log(post.age);

8
@thejh Hừm, đó là một điểm tốt. Tuy nhiên, không khó để thêm điều đó, vì vậy tôi sẽ loại bỏ nó ra khỏi ví dụ để giữ mọi thứ đơn giản.
Casey Chu

72
Phát triển máy chủ web của node.js bị ảnh hưởng bởi middlewarez yêu cầu bạn phải nghiên cứu chúng hàng giờ để tiết kiệm cho bạn số phút mã hóa. Hãy để một mình tài liệu ít ỏi gần như tất cả chúng cung cấp. Và ứng dụng của bạn cuối cùng dựa vào tiêu chí của người khác, không phải của bạn. Cộng với bất kỳ số lượng các vấn đề hiệu suất.
Juan Lanus

4
var POST = qs.parse(body); // use POST chỉ dành cho những người như tôi: khi tên của trường văn bản đầu vào là "người dùng", Post.usersẽ hiển thị dữ liệu của trường đó. ví dụconsole.log(Post.user);
Michael Moeller

5
Bạn cũng có thể sử dụng hàm readablegọi lại thay vì xây dựng dữ liệu thành một chuỗi cơ thể. Khi nó được bắn, cơ thể có sẵn thông quarequest.read();
Thomas Fankhauser

4
Lưu ý rằng req.connection.destroy(); không ngăn chặn các cuộc gọi lại được thực thi! Ví dụ, cuộc gọi lại "vào cuối" sẽ được thực hiện với phần thân bị cắt cụt! Đây có lẽ không phải là điều bạn muốn ...
collimarco

149

Đảm bảo tắt kết nối nếu ai đó cố gắng làm ngập RAM của bạn!

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
Bạn cũng có thể trả về Mã lỗi HTTP 413 (Thực thể yêu cầu quá lớn)
neoascetic

1
@SSHThis: Không, đó là 1 * 10 ^ 6 = 1000000.
thejh

@tq: trong trường hợp này, POST [name] (ví dụ POST ["foo"]).
13 lúc 21 giờ 43 phút

2
var POST = qs.parse(body); // use POST chỉ dành cho noobs: khi tên của trường văn bản đầu vào là "người dùng", Post.user sẽ hiển thị dữ liệu của trường đó. ví dụ: console.log (Post.user);
Michael Moeller

2
Ai đó có thể giúp tôi không, nếu tôi đăng {'Tên': 'Joe'} Tôi nhận được {{'Tên': 'Joe'}: ''} sau qs.Pude (POST) ...
Matt Canty

118

Rất nhiều câu trả lời ở đây không còn là thực tiễn tốt nữa hoặc không giải thích bất cứ điều gì, vì vậy đó là lý do tại sao tôi viết bài này.

Khái niệm cơ bản

Khi cuộc gọi lại của http.createServer được gọi, là khi máy chủ thực sự đã nhận được tất cả các tiêu đề cho yêu cầu, nhưng có thể dữ liệu chưa được nhận, vì vậy chúng tôi phải chờ. Các đối tượng yêu cầu http (một trường hợp http.IncomingMessage) thực sự là một thể đọc được dòng . Trong các luồng có thể đọc được bất cứ khi nào một khối dữ liệu đến, một sự kiện được phát ra (giả sử bạn đã đăng ký gọi lại cho nó) và khi tất cả các khối đã đến thì một sự kiện được phát ra. Đây là một ví dụ về cách bạn lắng nghe các sự kiện: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)

Chuyển đổi bộ đệm thành chuỗi

Nếu bạn thử điều này, bạn sẽ nhận thấy các khối là bộ đệm . Nếu bạn không xử lý dữ liệu nhị phân và cần phải làm việc với các chuỗi thay vào đó, tôi khuyên bạn nên sử dụng phương thức request.setEncoding , điều này khiến các luồng phát ra chuỗi được diễn giải với mã hóa đã cho và xử lý đúng các ký tự nhiều byte.

Đệm chun

Bây giờ có lẽ bạn không quan tâm đến từng đoạn bởi chính nó, vì vậy trong trường hợp này có lẽ bạn muốn đệm nó như thế này:

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)

Ở đây Buffer.concat được sử dụng, đơn giản là ghép tất cả các bộ đệm và trả về một bộ đệm lớn. Bạn cũng có thể sử dụng mô-đun concat-stream , hoạt động tương tự:

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

Phân tích nội dung

Nếu bạn đang cố gắng để chấp nhận HTML hình POST trình không có các tập tin hoặc bàn giao ajax jQuery cuộc gọi với kiểu nội dung mặc định, sau đó các loại nội dung là application/x-www-form-urlencodedvới uft-8mã hóa. Bạn có thể sử dụng mô-đun chuỗi truy vấn để hủy tuần tự hóa nó và truy cập các thuộc tính:

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)

Nếu loại nội dung của bạn là JSON thay vào đó, bạn chỉ cần sử dụng JSON.parse thay vì qs.parse .

Nếu bạn đang xử lý các tệp hoặc xử lý loại nội dung nhiều phần, thì trong trường hợp đó, bạn nên sử dụng một cái gì đó giống như ghê gớm để loại bỏ tất cả nỗi đau khi xử lý nó. Hãy xem câu trả lời khác này của tôi, nơi tôi đã đăng các liên kết và mô-đun hữu ích cho nội dung nhiều phần.

Đường ống

Nếu bạn không muốn phân tích nội dung mà chuyển nó sang một nơi khác, ví dụ gửi nó đến một yêu cầu http khác dưới dạng dữ liệu hoặc lưu nó vào một tệp tôi khuyên bạn nên chuyển nó chứ không phải đệm nó, vì nó sẽ ít hơn mã, xử lý áp lực trở lại tốt hơn, nó sẽ chiếm ít bộ nhớ hơn và trong một số trường hợp nhanh hơn.

Vì vậy, nếu bạn muốn lưu nội dung vào một tệp:

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

Giới hạn số lượng dữ liệu

Như các câu trả lời khác đã lưu ý rằng các khách hàng độc hại có thể gửi cho bạn một lượng dữ liệu khổng lồ để làm hỏng ứng dụng của bạn hoặc lấp đầy bộ nhớ của bạn để đảm bảo rằng bạn bỏ các yêu cầu phát ra dữ liệu vượt qua một giới hạn nhất định. Nếu bạn không sử dụng thư viện để xử lý dữ liệu đến. Tôi sẽ đề nghị sử dụng một cái gì đó như máy đo luồng có thể hủy yêu cầu nếu đạt đến giới hạn chỉ định:

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

hoặc là

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

hoặc là

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

Mô-đun NPM

Trong khi tôi đã mô tả ở trên về cách bạn có thể sử dụng phần thân yêu cầu HTTP, chỉ đơn giản là đệm và phân tích nội dung, tôi đề nghị sử dụng một trong các mô-đun này thay vì tự thực hiện vì chúng có thể sẽ xử lý các trường hợp cạnh tốt hơn. Để thể hiện tôi đề nghị sử dụng trình phân tích cú pháp cơ thể . Đối với koa, có một mô-đun tương tự .

Nếu bạn không sử dụng khung, cơ thể khá tốt.


Cảm ơn, tôi đã sử dụng mã của bạn và tôi nhận được tin nhắn trùng lặp bí ẩn. Có thể là biến requestđược sử dụng lại và request.on('end')được gọi nhiều lần? Làm thế nào tôi có thể tránh điều đó?
Yan King Yin

Tôi không thể biết tại sao mà không thấy mã của bạn. Lưu ý rằng đối với mọi yêu cầu, request.on('end', ...)sẽ được gọi.
Farid Nouri Neshat

Có lẽ nó không liên quan đến mã của bạn, tôi đang thực hiện các sự kiện do máy chủ gửi và có thể đã làm hỏng nó ... mã của bạn vẫn hoạt động tốt, dù sao cũng cảm ơn :)
Yan King Yin

Làm thế nào điều này có hiệu quả khi so sánh với việc xử lý một yêu cầu GET mà không có trình xử lý 'end', tức là không có bộ đệm?
JSON

1
Đây là câu trả lời tốt nhất cho câu hỏi. 🧐
montrealist

103

Đây là một trình bao bọc không có khung rất đơn giản dựa trên các câu trả lời và bài viết khác được đăng ở đây:

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

Ví dụ sử dụng:

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

Không nên chuyển séc này sang một phần mềm trung gian riêng biệt để nó có thể kiểm tra các yêu cầu quá lớn đối với tất cả các yêu cầu đăng / đặt
Pavel Nikolov 23/2/13

@PavelNikolov điều này có nghĩa chủ yếu cho các công việc nhanh chóng và bẩn thỉu, nếu không, có lẽ tốt hơn là sử dụng Express như câu trả lời được chấp nhận ở đây khuyến nghị (có lẽ cũng đảm nhiệm việc quản lý các yêu cầu lớn). Hãy thoải mái sửa đổi và "fork" nó theo ý thích của bạn mặc dù.
Mahn

Còn phương thức .read () thì sao? Điều đó không được hỗ trợ bởi mô-đun http? Ví dụ. answer.read ()
BT

Này, chỉ tò mò - tại sao bạn lại đặt tải trọng vào đối tượng phản hồi (answer.post) chứ không phải đối tượng yêu cầu?
Jotham

@Jotham câu hỏi hay ... Tôi không biết tại sao tôi không nhận thấy điều đó sớm hơn, nhưng không có lý do tại sao nó nên response.postthay vì logic hơn request.post. Tôi đã cập nhật bài viết.
Mahn

83

Sẽ sạch hơn nếu bạn mã hóa dữ liệu của mình sang JSON , sau đó gửi nó đến 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
Đây là những gì làm việc cho tôi. Hóa ra các giải pháp khác trả về một chuỗi trông giống như JSON nhưng không được phân tích cú pháp. Thay vì qs.parse(), JSON.parse()biến cơ thể thành một cái gì đó có thể sử dụng. Ví dụ : var post = JSON.parse(body);, sau đó truy cập dữ liệu với post.fieldname. (Đạo đức của câu chuyện, nếu bạn đang nhầm lẫn về những gì bạn đang nhìn thấy, đừng quên về typeof!)
wmassingham

12
Cũng cần lưu ý rằng bạn phải thử bắt hàm JSON.parse vì nếu tôi muốn làm hỏng ứng dụng của bạn, hãy gửi một phần thân có văn bản thô.
ecarrizo

Bạn nên sử dụng request.setEncodingđể làm cho công việc này đúng cách, nó có thể không xử lý các ký tự không phải ascii đúng cách.
Farid Nouri Neshat

37

Đối với bất cứ ai tự hỏi làm thế nào để thực hiện nhiệm vụ tầm thường này mà không cần cài đặt một khung web tôi đã quản lý để kết nối nó với nhau. Khó sản xuất sẵn sàng nhưng nó dường như làm việc.

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

Cuối cùng, một giải pháp HOÀN TOÀN HOÀN TOÀN cho vấn đề kỳ lạ này..cũng câu trả lời trước đó đã giúp rất nhiều để hiểu tại sao không có bất kỳ dữ liệu nào trong yêu cầu khi cuộc gọi lại bắt đầu .. Rất cám ơn!
luis-br

3
1) Câu trả lời này giả sử dữ liệu là một chuỗi. Giả định xấu, trong một trường hợp chung. 2) Câu trả lời này giả định rằng dữ liệu đến trong một đoạn. Nếu không, chia tách bằng '=' sẽ cho kết quả không thể đoán trước. Giả định xấu, trong một trường hợp chung.
Konstantin

@Konstantin Thật ra câu trả lời này giả sử dữ liệu là Bộ đệm. Kiểm tra này. stackoverflow.com/questions/14551194/ cũng Ngoài ra. millermedeiros.github.io/mdoc/examples/node_api/doc/NH
Shawn Whinnery

16

Bạn có thể sử dụng body-parser, phần mềm trung gian phân tích cú pháp cơ thể Node.js.

Tải đầu tiên body-parser

$ npm install body-parser --save

Một số ví dụ mã

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

Thêm tài liệu có thể được tìm thấy ở đây



9

Đây là cách bạn có thể làm điều đó nếu bạn sử dụng nút-formidable :

var formidable = require("formidable");

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

Tôi gặp sự cố với đường dẫn, khi tôi cố gắng sử dụng đường dẫn hoặc đường dẫn + tên để truy cập tệp bằng lwip.open (đường dẫn hoặc đường dẫn + tên tôi đang gặp lỗi là hình ảnh không thể lấy được.
Lion789

7

Nếu bạn thích sử dụng Node.js thuần thì bạn có thể trích xuất dữ liệu POST như được hiển thị bên dưới:

// 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) Cài đặt 'body-parser'từ npm.

2) Sau đó, trong ứng dụng của bạn .

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

3) sau đó bạn cần viết

app.use(bodyParser.json())

trong mô-đun app.ts

4) hãy nhớ rằng bạn bao gồm

app.use(bodyParser.json())

trong đầu hoặc trước bất kỳ tuyên bố mô-đun.

Ví dụ:

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

5) Sau đó sử dụng

var postdata = req.body;

5

Nếu bạn không muốn chia nhỏ dữ liệu của mình cùng với cuộc datagọi lại, bạn luôn có thể sử dụng cuộc readablegọi lại như thế này:

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

Cách tiếp cận này sửa đổi yêu cầu đến, nhưng ngay sau khi bạn hoàn thành phản hồi của mình, yêu cầu sẽ được thu gom rác, do đó không phải là vấn đề.

Một phương pháp tiên tiến sẽ là kiểm tra kích thước cơ thể trước, nếu bạn sợ cơ thể to lớn.


Cách thuận tiện để làm điều đó, nhưng làm thế nào để bạn "kiểm tra kích thước cơ thể trước" theo cách không thể bị lừa bởi một yêu cầu độc hại?
doug65536

requestlà một luồng node.js bình thường, vì vậy bạn có thể kiểm tra request.headersđộ dài cơ thể và hủy yêu cầu nếu cần.
Thomas Fankhauser

1
@ThomasFankhauser Chiều dài cơ thể trong tiêu đề có thể không phải là giá trị chính xác hoặc thậm chí hiện tại. Cách đúng đắn để làm điều đó là khi cơ thể đến và bạn đang đệm nó, bạn kiểm tra kích thước để đảm bảo nó không vượt qua giới hạn.
Farid Nouri Neshat

4

Có nhiều cách để làm điều đó. Tuy nhiên, cách nhanh nhất mà tôi biết là sử dụng thư viện Express.js với trình phân tích cú pháp cơ thể.

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

Điều đó có thể làm việc cho các chuỗi, nhưng tôi sẽ thay đổi bodyParser.urlencoding thành bodyParser.json thay vào đó nếu dữ liệu POST chứa một mảng JSON.

Thông tin thêm: http://www.kompulsa.com/how-to-accept-and-parse-post-requests-in-node-js/


4

Bạn cần nhận POSTdữ liệu theo từng khối bằng cách sử dụngrequest.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)

Bạn nên xem xét thêm giới hạn kích thước tại vị trí được chỉ định như đề xuất .


Đây có phải, nhiều hơn, dễ bị tấn công loris chậm?

Nodejs ít nhạy cảm với loris chậm hơn, ví dụ, php - bởi vì nó không xây dựng một đối tượng phiên lớn xung quanh mỗi kết nối http. Tuy nhiên, có vẻ như mã này vẫn có thể giới thiệu một lỗ hổng chậm loris. Điều này có thể được ngăn chặn bằng cách setTimeoutkết thúc kết nối sau một khoảng thời gian nhất định, nếu không nhận được yêu cầu đầy đủ trong cửa sổ đó.
Gershom


3

Nếu bạn đang sử dụng Express.js , trước khi bạn có thể truy cập vào req.body, bạn phải thêm bodyParser trung gian:

app.use(express.bodyParser());

Sau đó, bạn có thể yêu cầu

req.body.user

Hầu hết các phần mềm trung gian (như bodyParser) không còn được đóng gói với Express và phải được cài đặt riêng. Xem câu trả lời từ @ nikodean2 ở trên để có câu trả lời mới hơn
Jeff Collier

app.use (bodyParser ()); hoạt động nhưng đang mang lại cho tôi thông báo lỗi đỏ
Chris Allinson

2

Và nếu bạn không muốn sử dụng toàn bộ khung như Express, nhưng bạn cũng cần các loại biểu mẫu khác nhau, bao gồm cả tải lên, thì formaline có thể là một lựa chọn tốt.

Nó được liệt kê trong các mô-đun Node.js


1

Tôi đã tìm thấy một video giải thích về cách đạt được điều này: https://www.youtube.com/watch?v=nuw48-u3Yrg

Nó sử dụng mô-đun "http" mặc định cùng với các mô-đun "chuỗi truy vấn" và "chuỗi xây dựng". Ứng dụng lấy hai số (sử dụng hai hộp văn bản) từ một trang web và sau khi gửi, trả về tổng của hai số đó (cùng với việc duy trì các giá trị trong hộp văn bản). Đây là ví dụ tốt nhất tôi có thể tìm thấy ở bất cứ nơi nào khác.

Mã nguồn liên quan:

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

Đối với những người sử dụng tải lên POST nhị phân thô mà không cần mã hóa, bạn có thể sử dụng:

khách hàng

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

người phục vụ:

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

Bạn có thể sử dụng phần mềm trung gian cấp tốc , hiện có trình phân tích cú pháp cơ thể được tích hợp trong nó. Điều này có nghĩa là tất cả những gì bạn cần làm là như sau:

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

Ví dụ mã đó là ES6 với Express 4.16.x


0

bạn có thể trích xuất tham số bài mà không cần sử dụng express.

1: nmp install multiparty

2: nhập khẩu nhiều bên. như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: và MẪU HTML LÀ.

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

Tôi hy vọng điều này sẽ làm việc cho bạn. Cảm ơn.


0

Giới hạn kích thước POST tránh làm ngập ứng dụng nút của bạn. Có một mô-đun thô cơ thể tuyệt vời , phù hợp cho cả thể hiện và kết nối, có thể giúp bạn giới hạn yêu cầu theo kích thước và độ dài.


0

Nếu nó liên quan đến tải lên tệp, trình duyệt thường gửi dưới dạng loại "multipart/form-data"nội dung. Bạn có thể sử dụng điều này trong những trường hợp như vậy

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

Tham khảo 1

Tham khảo 2


0

Trên các trường mẫu như thế này

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

một số câu trả lời ở trên sẽ thất bại vì chúng chỉ hỗ trợ dữ liệu phẳng.

Hiện tại tôi đang sử dụng câu trả lời của Casey Chu nhưng với mô-đun "qs" thay vì mô-đun "chuỗi truy vấn". Đây là mô-đun "body-Parser" cũng sử dụng. Vì vậy, nếu bạn muốn dữ liệu lồng nhau, bạn phải cài đặt qs.

npm install qs --save

Sau đó thay thế dòng đầu tiên như:

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

Bạn có thể dễ dàng gửi và nhận phản hồi của yêu cầu POST bằng cách sử dụng "Yêu cầu - Máy khách HTTP được đơn giản hóa" và Promise Javascript.

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

Bạn cần sử dụng bodyParser () nếu bạn muốn dữ liệu biểu mẫu có sẵn trong req.body. body-Parser phân tích cú pháp yêu cầu của bạn và chuyển đổi nó thành định dạng mà từ đó bạn có thể dễ dàng trích xuất thông tin liên quan mà bạn có thể cần.

Ví dụ: giả sử bạn có một mẫu đăng ký tại lối vào của bạn. Bạn đang điền nó và yêu cầu máy chủ lưu các chi tiết ở đâu đó.

Trích xuất tên người dùng và mật khẩu từ yêu cầu của bạn sẽ đơn giản như dưới đây nếu bạn sử dụng trình phân tích cú pháp cơ thể.

Phần cứng của chúng tôi

var loginDetails = {

username : request.body.username,

password : request.body.password

};

0

MỘT DÒNG mà không có phần mềm trung gian
Nếu bạn đăng dữ liệu sau,
'name':'ABC'
thì bạn có thể phân tích cú pháp bằng cách sử dụng một lớp lót sau,

require('url').parse(req.url, true).query.name
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.