Node.js에서 POST 데이터를 처리하는 방법은 무엇입니까?
Node.jsform[method="post"]
의 HTTP POST
메서드에서 보낸 양식 데이터 ( ) 및 파일 업로드를 어떻게 추출 합니까?
나는 문서를 읽고, 봤지만 아무것도 찾지 못했습니다.
function (request, response) {
//request.post????
}
도서관이나 해킹이 있습니까?
당신이 사용하는 경우 익스프레스 (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)
});
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);
누군가 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
});
}
}
여기에 게시 된 다른 답변과 기사를 기반으로 한 매우 간단한 프레임 워크가없는 래퍼가 있습니다.
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);
여기에 많은 답변이 더 이상 좋은 관행이 아니거나 설명이 없기 때문에 제가 이것을 쓰는 이유입니다.
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를 아약스 의 기본 콘텐츠 형식으로 호출 한 다음 콘텐츠 형식입니다 application/x-www-form-urlencoded
으로 uft-8
인코딩. querystring 모듈 을 사용하여 직렬화를 해제하고 속성에 액세스 할 수 있습니다.
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 인 경우 qs.parse 대신 JSON.parse를 사용하면 됩니다 .
파일을 다루거나 멀티 파트 콘텐츠 유형을 처리하는 경우,이 경우 처리로 인한 모든 고통을 제거하는 강력한 것과 같은 것을 사용해야합니다. 내가 여러 부분으로 된 콘텐츠에 대한 유용한 링크와 모듈을 게시 한 다른 답변 을 살펴보십시오 .
콘텐츠를 구문 분석하지 않고 다른 곳으로 전달하는 경우, 예를 들어 데이터로 다른 http 요청으로 보내거나 파일에 저장하는 경우 버퍼링보다는 파이핑하는 것이 좋습니다. 코드를 사용하면 배압을 더 잘 처리 할 수 있으며 메모리 사용량이 적고 경우에 따라 더 빠릅니다.
따라서 콘텐츠를 파일에 저장하려면 :
http.createServer((request, response) => {
request.pipe(fs.createWriteStream('./request'));
}).listen(8080)
다른 답변에서 언급했듯이 악의적 인 클라이언트가 엄청난 양의 데이터를 보내어 응용 프로그램을 충돌 시키거나 메모리를 채울 수 있으므로 데이터를 내보내는 요청이 특정 제한을 통과하는지 확인하도록 보호합니다. 들어오는 데이터를 처리하기 위해 라이브러리를 사용하지 않는 경우. 지정된 제한에 도달하면 요청을 중단 할 수있는 stream-meter 와 같은 것을 사용하는 것이 좋습니다 .
limitedStream = request.pipe(meter(1e7));
limitedStream.on('data', ...);
limitedStream.on('end', ...);
또는
request.pipe(meter(1e7)).pipe(createWriteStream(...));
또는
concat(request.pipe(meter(1e7)), ...);
또한 npm 모듈을 직접 구현하는 것보다 사용하려고 시도하십시오. 아마도 가장자리 사례를 더 잘 처리 할 것입니다. 표현을 위해 body-parser를 사용하는 것이 좋습니다 . koa의 경우 유사한 모듈이 있습니다.
프레임 워크를 사용하지 않으면 신체 가 꽤 좋습니다.
데이터를 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));
});
}
}
웹 프레임 워크를 설치하지 않고이 사소한 작업을 수행하는 방법을 궁금해하는 사람을 위해 함께이 작업을 수행했습니다. 거의 생산 준비가되지 않았지만 작동하는 것 같습니다.
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);
})
}
}
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);
})
참조 : 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
});
node-formidable 을 사용하는 경우 방법은 다음과 같습니다 .
var formidable = require("formidable");
var form = new formidable.IncomingForm();
form.parse(request, function (err, fields) {
console.log(fields.parameter1);
console.log(fields.parameter2);
// ...
});
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
});
이 접근 방식은 들어오는 요청을 수정하지만 응답을 완료하자마자 요청이 가비지 수집되므로 문제가되지 않습니다.
고급 접근 방식은 거대한 몸을 두려워하는 경우 먼저 몸 크기를 확인하는 것입니다.
순수한 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}`);
});
1) 'body-parser'
npm에서 설치합니다 .
2) 그런 다음 app.ts에서
var bodyParser = require('body-parser');
3) 그런 다음 작성해야합니다
app.use(bodyParser.json())
에서 app.ts 모듈
4) 다음을 포함한다는 것을 명심하십시오.
app.use(bodyParser.json())
모듈 선언의 맨 위 또는 앞에.
전의:
app.use(bodyParser.json())
app.use('/user',user);
5) 사용
var postdata = req.body;
이를 수행하는 방법에는 여러 가지가 있습니다. 그러나 내가 아는 가장 빠른 방법은 body-parser와 함께 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);
그것은 문자열에 대해 작동 할 수 있지만 POST 데이터에 JSON 배열이 포함되어 있으면 bodyParser.urlencoded를 bodyParser.json으로 변경합니다.
추가 정보 : http://www.kompulsa.com/how-to-accept-and-parse-post-requests-in-node-js/
다음을 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가 제안한 대로 표시된 위치에 크기 제한을 추가하는 것을 고려해야 합니다.
Express.js 를 사용 하는 경우 req.body에 액세스하려면 먼저 미들웨어 bodyParser를 추가해야합니다.
app.use(express.bodyParser());
그런 다음 요청할 수 있습니다.
req.body.user
Express와 같은 전체 프레임 워크를 사용하고 싶지 않지만 업로드를 포함하여 다른 종류의 양식도 필요하다면 포르말린 이 좋은 선택 일 수 있습니다.
Node.js 모듈에 나열되어 있습니다.
이를 달성하는 방법을 설명하는 비디오를 찾았습니다 : 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);
사용하는 사람들을 위해 원시 이진 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!");
});
});
이제 body-parser가 내장 된 express 미들웨어를 사용할 수 있습니다 . 즉, 다음 만 수행하면됩니다.
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)
})
해당 코드 예제는 Express 4.16.x가 설치된 ES6입니다.
익스프레스를 사용하지 않고 포스트 매개 변수를 추출 할 수 있습니다.
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>
이것이 당신에게 효과가 있기를 바랍니다. 감사.
POST 크기를 제한하여 노드 앱 플러드를 방지하십시오. 크기와 길이에 따라 요청을 제한하는 데 도움이 될 수있는 Express 및 Connect 모두에 적합한 훌륭한 raw-body 모듈이 있습니다.
파일 업로드가 포함 된 경우 브라우저는 일반적으로 "multipart/form-data"
콘텐츠 유형 으로 전송합니다 . 이런 경우에 사용할 수 있습니다.
var multipart = require('multipart');
multipart.parse(req)
이와 같은 양식 필드
<input type="text" name="user[name]" value="MyName">
<input type="text" name="user[email]" value="myemail@somewherefarfar.com">
위의 답변 중 일부는 플랫 데이터 만 지원하므로 실패합니다.
지금은 Casey Chu 대답을 사용하고 있지만 "querystring"모듈 대신 "qs"를 사용합니다. 이것은 "body-parser"가 사용 하는 모듈 이기도합니다. 따라서 중첩 된 데이터를 원하면 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.
});
}
}
"Request-Simplified HTTP client"및 Javascript Promise를 사용하여 POST 요청에 대한 응답을 쉽게 보내고받을 수 있습니다.
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);
}
});
});
}
req.body에서 양식 데이터를 사용할 수 있도록하려면 bodyParser ()를 사용해야합니다. body-parser는 요청을 구문 분석하고 필요한 관련 정보를 쉽게 추출 할 수있는 형식으로 변환합니다.
예를 들어 프런트 엔드에 가입 양식이 있다고 가정 해 보겠습니다. 당신은 그것을 채우고 서버에 세부 사항을 어딘가에 저장하도록 요청합니다.
요청에서 사용자 이름과 비밀번호를 추출하는 것은 body-parser를 사용하는 경우 아래와 같이 간단합니다.
…………………………………………………….
var loginDetails = {
username : request.body.username,
password : request.body.password
};
Express v4.17.0
app.use(express.urlencoded( {extended: true} ))
참고 URL : https://stackoverflow.com/questions/4295782/how-to-process-post-data-in-node-js
'program story' 카테고리의 다른 글
.gitignore에서 무시되는 특정 파일을 표시하는 Git 명령 (0) | 2020.10.03 |
---|---|
어느 것이 더 빠릅니까 : while (1) 또는 while (2)? (0) | 2020.10.03 |
기본 / 내장 앱을 사용하지 않고 JavaMail API를 사용하여 Android에서 이메일 보내기 (0) | 2020.10.02 |
PHP에서 JavaScript로 변수와 데이터를 어떻게 전달합니까? (0) | 2020.10.02 |
조각에서 컨텍스트 사용 (0) | 2020.10.02 |