[node.js] Node.js-Express를 사용하여 원시 요청 본문 가져 오기

Express를 사용할 때 내 코드는 다음과 같습니다.

app.use(express.bodyParser());

원시 요청 본문 은 어떻게 얻 습니까?



답변

편집 2 : 본문 파서 모듈의 1.15.2 릴리스 에서는 본문을 Buffer 로 반환하는 원시 모드를 도입 합니다 . 기본적으로 deflate 및 gzip 압축 해제도 자동으로 처리합니다. 사용 예 :

var bodyParser = require('body-parser');
app.use(bodyParser.raw(options));

app.get(path, function(req, res) {
  // req.body is a Buffer object
});

기본적으로 options개체에는 다음과 같은 기본 옵션이 있습니다.

var options = {
  inflate: true,
  limit: '100kb',
  type: 'application/octet-stream'
};

원시 파서가 이외의 다른 MIME 유형을 구문 분석 application/octet-stream하도록하려면 여기에서 변경해야합니다. 또한 같은 와일드 카드 매칭을 지원 */*하거나 */application.


참고 : 다음 답변은 미들웨어가 여전히 프레임 워크와 번들로 제공되는 Express 4 이전 버전에 대한 것입니다. 현대에 해당하는 것은 body-parser입니다. 별도로 설치해야하는 모듈입니다.

rawBodyExpress 의 속성은 한 번 사용할 수 있었지만 버전 1.5.1부터 제거되었습니다. 원시 요청 본문을 얻으려면 bodyParser를 사용하기 전에 미들웨어를 넣어야합니다. 여기 에서 GitHub 토론을 읽을 수도 있습니다 .

app.use(function(req, res, next) {
  req.rawBody = '';
  req.setEncoding('utf8');

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

  req.on('end', function() {
    next();
  });
});
app.use(express.bodyParser());

해당 미들웨어는 실제 데이터 스트림에서 읽고이를 rawBody요청 속성에 저장합니다 . 그런 다음 다음과 같이 원시 본문에 액세스 할 수 있습니다.

app.post('/', function(req, res) {
  // do something with req.rawBody
  // use req.body for the parsed body
});

편집 : 이 메서드와 bodyParser가 공존하는 것을 거부하는 것 같습니다. 왜냐하면 하나는 다른 하나보다 먼저 요청 스트림을 소비하여 둘 중 하나가 두 번째로 실행되지 end않아 절대 호출하지 않고 next()응용 프로그램을 중단하기 때문입니다.

가장 간단한 해결책은 Connect의 JSON 파서 57 행에서 찾을 수있는 bodyParser의 소스를 수정하는 것 입니다. 이것이 수정 된 버전의 모습입니다.

var buf = '';
req.setEncoding('utf8');
req.on('data', function(chunk){ buf += chunk });
req.on('end', function() {
  req.rawBody = buf;
  var first = buf.trim()[0];
  ...
});

다음 위치에서 파일을 찾을 수 있습니다.

/node_modules/express/node_modules/connect/lib/middleware/json.js.


답변

bodyParser의 verify콜백을 사용하여 bodyParser와 잘 어울리는 솔루션을 얻었 습니다. 이 코드에서는 콘텐츠의 sha1을 얻고 원시 본문도 가져 오는 데 사용하고 있습니다.

app.use(bodyParser.json({
    verify: function(req, res, buf, encoding) {

        // sha1 content
        var hash = crypto.createHash('sha1');
        hash.update(buf);
        req.hasha = hash.digest('hex');
        console.log("hash", req.hasha);

        // get rawBody        
        req.rawBody = buf.toString();
        console.log("rawBody", req.rawBody);

    }
}));

저는 Node.js와 express.js (어제 시작되었습니다. 문자 그대로!)를 처음 사용하므로이 솔루션에 대한 의견을 듣고 싶습니다.


답변

이 솔루션은 저에게 효과적이었습니다.

var rawBodySaver = function (req, res, buf, encoding) {
  if (buf && buf.length) {
    req.rawBody = buf.toString(encoding || 'utf8');
  }
}

app.use(bodyParser.json({ verify: rawBodySaver }));
app.use(bodyParser.urlencoded({ verify: rawBodySaver, extended: true }));
app.use(bodyParser.raw({ verify: rawBodySaver, type: '*/*' }));

req.on('data', function(chunk) { });청크 요청 본문에서 작동하지 않는 솔루션을 사용할 때 .


답변

json, urlencoded 등을 지원하려는 경우 bodyParser에서 제대로 재생되지 않으므로 다른 답변에주의하십시오. bodyParser와 함께 작동하도록하려면 처리기를 조건화하여 Content-Type헤더 에만 등록해야 합니다. bodyParser 자체처럼

와 요청의 원시 본문 내용 얻으려면 Content-Type: "text/plain"req.rawBody당신이 할 수 있습니다 :

app.use(function(req, res, next) {
  var contentType = req.headers['content-type'] || ''
    , mime = contentType.split(';')[0];

  if (mime != 'text/plain') {
    return next();
  }

  var data = '';
  req.setEncoding('utf8');
  req.on('data', function(chunk) {
    data += chunk;
  });
  req.on('end', function() {
    req.rawBody = data;
    next();
  });
});


답변

이것은 위의 hexacyanide의 대답에 대한 변형입니다. 이 미들웨어는 ‘데이터’이벤트도 처리하지만 ‘next’를 호출하기 전에 데이터가 소비 될 때까지 기다리지 않습니다. 이렇게하면이 미들웨어와 bodyParser가 공존하여 스트림을 병렬로 소비 할 수 있습니다.

app.use(function(req, res, next) {
  req.rawBody = '';
  req.setEncoding('utf8');

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

  next();
});
app.use(express.bodyParser());


답변

본문 파서 사용 본문을 다음과 같이 구문 분석합니다.

app.use(bodyParser.text());

app.use(bodyParser.urlencoded());

app.use(bodyParser.raw());

app.use(bodyParser.json());

즉. 원시 텍스트 파일을 얻으려면 다음을 실행하십시오..text() .

그것이 body-parser가 현재 지원하는 것입니다.


답변