Node.js - एक्सप्रेस का उपयोग करके कच्चा अनुरोध निकाय प्राप्त करें


जवाबों:


89

संपादित करें 2: बॉडी पार्सर मॉड्यूल के 1.15.2 रिलीज कच्चे मोड का परिचय देता है , जो शरीर को बफर के रूप में लौटाता है । डिफ़ॉल्ट रूप से, यह स्वचालित रूप से अपस्फीति और गज़िप अपघटन को भी संभालता है। उदाहरण उपयोग:

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


नोट: निम्नलिखित उत्तर एक्सप्रेस 4 से पहले के संस्करणों के लिए है, जहां मिडलवेयर अभी भी ढांचे के साथ बंडल किया गया था। आधुनिक समकक्ष बॉडी-पार्सर मॉड्यूल है, जिसे अलग से स्थापित किया जाना चाहिए।

rawBodyएक्सप्रेस में संपत्ति एक बार उपलब्ध था, लेकिन संस्करण 1.5.1 के बाद से हटा दिया। कच्चा अनुरोध निकाय प्राप्त करने के लिए, आपको बॉडीपार का उपयोग करने से पहले कुछ मिडलवेयर में डालना होगा। आप इसके बारे में 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
});

संपादित करें: ऐसा लगता है कि यह विधि और बॉडीपार सह-अस्तित्व के लिए मना कर देती है, क्योंकि एक दूसरे से पहले अनुरोध स्ट्रीम का उपभोग करेगा, जो कभी भी आग न लगाने के लिए दूसरा है end, इस प्रकार कभी फोन नहीं करता है next(), और आपके आवेदन को लटका देता है।

सबसे सरल समाधान बॉडीपार के स्रोत को संशोधित करने की सबसे अधिक संभावना होगी, जो आपको कनेक्ट के JSON पार्सर की लाइन 57 पर मिलेगा । यह वह है जो संशोधित संस्करण जैसा दिखेगा।

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


ऐसा लगता है कि हम ऐसा नहीं कर सकते। अगर मैं इन कोड को जोड़ता हूं, तो \ n नोड्स / एक्सप्रेस \ नोड_मॉड्यूल्स \ कनेक्ट \ lib \ मिडलवेयर \ urlencoded.js की घटनाओं को निकाल नहीं दिया जाएगा। req.on ("data"), req.on ("end") निकाल नहीं दिया गया
haitao_wu

अपना कोड जोड़ने के बाद, मैं अपनी पोस्ट को इस कोड app.post ("/ ajax", function (req, res) {res.send ('हैलो वर्ल्ड, पोस्ट');) का उपयोग करता हूं। जब मेरे अनुरोध की सामग्री-प्रकार अनुप्रयोग / x-www-form-urlencoded है, तो सर्वर "हैलो वर्ल्ड, पोस्ट" का जवाब नहीं देगा
haitao_wu

मेरे मामले में फ़ाइल का स्थान गलत है .. मेरे पास एक्सप्रेस के नोड_मॉडल में कनेक्ट मॉड्यूल नहीं है (> 4.0.0) अभी तक नया स्थान नहीं मिला है
सैम व्लोबार्ग्स

एक्सप्रेस 4 में कनेक्ट निर्भरता नहीं है, और इसलिए इसमें बॉडी पार्सर मॉड्यूल नहीं है। यदि आपको अभी भी इसकी आवश्यकता है, तो आप इसे यहां पाएंगे ।
हेक्सासैनाइड

1
@hexacyanide क्या आप अपने उत्तर को अपडेट कर सकते हैं और नवीनतम बॉडी-पार्सर मिडलवेयर का संदर्भ शामिल कर सकते हैं ? मॉड्यूल में अब रॉ-बॉडी-पार्सर मिडलवेयर शामिल है । यह कच्चे शरीर को प्राप्त करने के लिए एक विधि की तलाश में googlers के लिए मददगार हो सकता है।
eAbi

47

मुझे एक समाधान मिला जो बॉडीपैर के साथ अच्छा खेलता है, बॉडीपेयर में verifyकॉलबैक का उपयोग करता है । इस कोड में, मैं इसका उपयोग सामग्री का एक 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 में नया हूं (कल शुरू हुआ, शाब्दिक रूप से!) तो मैं इस समाधान पर टिप्पणी सुनना चाहूंगा।


3
मुझे वास्तव में यह समाधान पसंद है। मैंने सिर्फ शामिल किया req.rawBody = buf.toString();और बाकी को verifyसमारोह से बाहर ले गया , क्योंकि मुझे बस इतना ही चाहिए था, और इसने खूबसूरती से काम किया। BodyParser स्रोत कोड को बदलने की कोई आवश्यकता नहीं है!
ग्रेग

+1 लेकिन मेरी समस्या अब यह है कि मुझे इस अनुरोध को सत्यापित करने के लिए एक async फ़ंक्शन की आवश्यकता है जो इस अनुरोध को पहले भेजा गया था या नहीं: /
Renato Gama

3
बहुत अच्छा। मेरा सुझाव है कि हो सकता हैreq.rawBody = buf.toString(encoding);
shaharsol

2
यह केवल application/jsonअनुरोधों को पकड़ लेगा
पावेल एवसिग्निव

35

इस समाधान ने मेरे लिए काम किया:

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) { });इसके साथ समाधान का उपयोग करता हूं तो यह अनुरोधित शरीर पर काम नहीं करता है।


इसने अनुरोध के विभिन्न हिस्सों में आने वाले डेटा के हर प्रमुख परिदृश्य का ध्यान रखा।
TWright

2
मैं एक Shopify ऐप webhook के लिए hmac को सत्यापित करने का प्रयास कर रहा था, और इसने मेरे लिए काम किया। मैंने इस उदाहरण का मोटे तौर पर पालन किया है: gist.github.com/andjosh/5c4f0244914adfd31244
चाड जॉनसन

29

उन अन्य उत्तरों के साथ सावधान रहें, क्योंकि वे बॉडीपेयर के साथ ठीक से नहीं खेलेंगे यदि आप भी json, urlencoded इत्यादि का समर्थन करना चाहते हैं, तो इसे बॉडीपेयर के साथ काम करने के लिए आप अपने हैंडलर को केवल 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();
  });
});

3
+1। मैंने ऊपर दिए गए समाधानों में से एक को आजमाया और फिर मेरे सभी GET और json पोस्ट विफल हो रहे थे। उपरोक्त समाधान तकनीकी रूप से प्रश्न के लिए सही हैं, लेकिन यदि आप एक से अधिक रूपों में डेटा के साथ अधिक विविध अनुरोधों को संभाल रहे हैं, तो आपको इसकी आवश्यकता होगी।

डेटा यहाँ क्या है? यह वह चर है जिसे हम UI से भेज रहे हैं?
सरस आर्य

app.use(bodyParser.urlencoded({limit: '80mb', extended: true})); app.use(bodyParser.json({limit: '80mb'})); app.use(bodyParser.raw({type: 'application/octet-stream'})) यह भी करेगा।
सौम्य कांति

15

यह ऊपर दिए गए हेक्सासैनाइड के उत्तर पर एक भिन्नता है। यह मिडिलवेयर 'डेटा' ईवेंट को भी हैंडल करता है, लेकिन 'नेक्स्ट' कॉल करने से पहले डेटा के उपभोग करने की प्रतीक्षा नहीं करता है। इस तरह यह दोनों मिडलवेयर और बॉडीपेयर कोएक्सिस्ट हो सकता है, जो कि समानांतर में धारा का उपभोग करता है।

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

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

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


2
यह लंबे शरीर पर काम नहीं करता है, जो जल्दी से कट जाते हैं।
एडम लॉकहार्ट

पूरी तरह से काम किया, मुझे बचाया। धन्यवाद।
हजकां

मैं पुष्टि कर रहा हूं कि यह बड़ी फ़ाइलों के लिए भी काम करता है। मैंने 1.5MB की एक पाठ फ़ाइल भेजने की कोशिश की और पूरा डेटा ठीक से प्राप्त हुआ। धन्यवाद
ATOzTOA

@AdamLockhart - आपके अनुरोधों को किस आकार में कटौती मिली?
UpTheCreek

@UpTheCreek, थोड़ी देर हो गई। निश्चित नहीं। मेरी नवीनतम सामग्री इस स्निपेट का उपयोग नहीं करती है, लेकिन यदि अन्य कोई समस्या नहीं रिपोर्ट करते हैं तो यह एक बग हो सकता है जिसे ठीक किया गया है।
एडम लॉकहार्ट

-1

बॉडी-पार्सर का उपयोग करें शरीर को पार्स करें जो यह होगा:

app.use(bodyParser.text());

app.use(bodyParser.urlencoded());

app.use(bodyParser.raw());

app.use(bodyParser.json());

अर्थात। यदि आपको कच्ची पाठ फ़ाइल मिलनी है, तो चलाएं .text()

वर्तमान में बॉडी-पार्सर का समर्थन करता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.