नोड / एक्सप्रेस में एक कस्टम http स्थिति संदेश कैसे भेजें?


89

मेरा नोड.जेएस ऐप को एक्सप्रेस / उदाहरण / एमएक्स ऐप की तरह बनाया गया है ।

एक नियंत्रक कार्रवाई में मैं एक कस्टम HTTP संदेश के साथ एक HTTP 400 स्थिति को बाहर थूकना चाहता हूं। डिफ़ॉल्ट रूप से http स्थिति संदेश "खराब अनुरोध" है:

HTTP/1.1 400 Bad Request

लेकिन मैं भेजना चाहता हूं

HTTP/1.1 400 Current password does not match

मैंने विभिन्न तरीकों की कोशिश की, लेकिन उनमें से किसी ने मेरे कस्टम संदेश को http स्थिति संदेश सेट नहीं किया।

मेरा वर्तमान समाधान नियंत्रक फ़ंक्शन ऐसा दिखता है:

exports.check = function( req, res) {
  if( req.param( 'val')!=='testme') {
    res.writeHead( 400, 'Current password does not match', {'content-type' : 'text/plain'});
    res.end( 'Current value does not match');

    return;
  } 
  // ...
}

सब कुछ ठीक काम करता है लेकिन ... ऐसा करने का यह सही तरीका नहीं है।

क्या एक्सप्रेस का उपयोग करके http स्थिति संदेश सेट करने का कोई बेहतर तरीका है?


4
ठीक है, यह केवल वर्कअराउंड प्रतीत होता है। लेकिन मैं ऐसा कुछ सलाह नहीं दूंगा, HTTP 1.1 कल्पना है कि यह त्रुटि विवरण कुछ अच्छे कारणों के लिए मानकीकृत है। मुझे लगता है कि कस्टम विवरण के साथ अच्छी तरह से ज्ञात स्थिति-कोड भेजने के लिए यह बुरा अभ्यास है, लेकिन यह आपके ऊपर है।
स्काहरमू

हम्म - शायद यह सच है। दूसरी ओर, मुझे लगता है कि ब्राउज़र केवल स्थिति कोड की जांच करेंगे और मानव पठनीय http स्थिति संदेश नहीं। मैंने सोचा कि यह एक अच्छा विचार है यदि उपलब्ध हो तो एक ठोस (यानी गैर डिफ़ॉल्ट) त्रुटि संदेश को परिवहन करने के लिए http स्थिति संदेश का उपयोग करें। प्लस कि ग्राहक पक्ष जावा स्क्रिप्ट (jQuery का उपयोग कर आप प्रदर्शन प्रयोजनों के लिए त्रुटि प्राप्त करने के लिए "jqXHR.statusText" कर सकते हैं) का उपयोग करना आसान है
10

4
यह संगतता या संभावित ब्राउज़र समस्याओं के बारे में नहीं है, यह सिर्फ बुरा अभ्यास है;) यदि आप प्रदर्शन के लिए एक त्रुटि संदेश चाहते हैं, तो इसे शरीर के रूप में भेजें, यही उद्देश्य है।
schaermu

6
विशिष्ट त्रुटि विवरण कल्पना का हिस्सा नहीं हैं। RCF-2616 विशेष रूप से बताता है: "HTTP / 1.1 के लिए परिभाषित संख्यात्मक स्थिति कोड के व्यक्तिगत मूल्य, और इसी कारण-वाक्यांश के एक उदाहरण सेट को नीचे प्रस्तुत किया गया है। यहां सूचीबद्ध कारण वाक्यांश केवल सिफारिशें हैं - उन्हें प्रतिस्थापित किया जाना चाहिए। प्रोटोकॉल को प्रभावित किए बिना स्थानीय समकक्ष। "
टेड बिगहम

कस्टम कारण वाक्यांश महान हैं, लेकिन (चूंकि आपका संदेश "वर्तमान पासवर्ड से मेल नहीं खाता है") ऐसा लगता है कि आप वास्तव में कोड 401 चाहते हैं, इस स्थिति में आपको शायद संदेश बदलने की आवश्यकता नहीं है।
Codebling

जवाबों:


59

आप विवरण के लिए इस res.send(400, 'Current password does not match') लुक एक्सप्रेस 3.x डॉक्स की जांच कर सकते हैं

Expressjs के लिए अद्यतन 4.x

इस तरह से उपयोग करें ( व्यक्त 4.x डॉक्स देखें ):

res.status(400).send('Current password does not match');
// or
res.status(400);
res.send('Current password does not match');

41
दुर्भाग्य से यह http स्थिति संदेश सेट नहीं करेगा, लेकिन 'वर्तमान पासवर्ड शरीर सामग्री के रूप में मेल नहीं खाता' ...
larsman

यह HTTP स्थिति सेट करता है, लेकिन एक चेतावनी फेंकता है क्योंकि यह विधि हस्ताक्षर हटा दिया गया है।
nullability

1
res.status(400).send('Current password does not match');उदाहरण एक्सप्रेस 4 के लिए मेरे लिए काम करता
टायलर कोलियर

में काम करता हैExpress ^4.16.2
अजय

103

मौजूदा उत्तरों में से कोई भी पूरा नहीं होता है जो ओपी ने मूल रूप से पूछा था, जो एक्सप्रेस द्वारा भेजे गए डिफ़ॉल्ट कारण-वाक्यांश (पाठ को स्थिति कोड के तुरंत बाद दिखाई देने वाला) को ओवरराइड करने के लिए है ।

तुम जो चाहते हो res.statusMessage। यह एक्सप्रेस का हिस्सा नहीं है, यह Node.js 0.11+ में अंतर्निहित http.Response ऑब्जेक्ट की एक संपत्ति है।

आप इसे इस तरह से उपयोग कर सकते हैं (एक्सप्रेस 4.x में परीक्षण किया गया है):

function(req, res) {
    res.statusMessage = "Current password does not match";
    res.status(400).end();
}

फिर curlयह सत्यापित करने के लिए उपयोग करें कि यह काम करता है:

$ curl -i -s http://localhost:3100/
HTTP/1.1 400 Current password does not match
X-Powered-By: Express
Date: Fri, 08 Apr 2016 19:04:35 GMT
Connection: keep-alive
Content-Length: 0


4
आप अंतर्निहित वस्तु के साथ संपत्ति प्राप्त कर सकते हैंres.nativeResponse.statusMessage
sebilasse

@RobertMoskal ने एक न्यूनतम एक्सप्रेस सर्वर (एक्सप्रेस 4.16.1 और नोड 12.9.0) का उपयोग करके परीक्षण किया, और यह अभी भी मेरे लिए काम करता है। अपना एप्लिकेशन कोड जांचें: शायद कुछ और गलत है।
ममाकोडन 13

निश्चित नहीं कि यह स्वीकृत उत्तर क्यों नहीं है क्योंकि यह निश्चित रूप से समाधान है, कम से कम मेरे द्वारा यह लिखते समय।
हारून समर्स

12

सर्वर साइड (एक्सप्रेस मिडलवेयर):

if(err) return res.status(500).end('User already exists.');

क्लाइंट की तरफ हैंडल करें

कोणीय: -

$http().....
.error(function(data, status) {
  console.error('Repos error', status, data);//"Repos error" 500 "User already exists."
});

jQuery: -

$.ajax({
    type: "post",
    url: url,
    success: function (data, text) {
    },
    error: function (request, status, error) {
        alert(request.responseText);
    }
});

11

एक्सप्रेस में इस तरह से कस्टम त्रुटियों को संभालने का एक सुंदर तरीका है:

function errorHandler(err, req, res, next) {
  var code = err.code;
  var message = err.message;
  res.writeHead(code, message, {'content-type' : 'text/plain'});
  res.end(message);
}

(आप इसके लिए एक्सप्रेस 'बिल्ट-इन एक्सप्रेस' का भी इस्तेमाल कर सकते हैं। हेराल्डर )

फिर अपने मार्गों से पहले अपने मिडलवेयर में:

app.use(errorHandler);

फिर जहां आप त्रुटि बनाना चाहते हैं 'वर्तमान पासवर्ड मेल नहीं खाता':

function checkPassword(req, res, next) {
  // check password, fails:
  var err = new Error('Current password does not match');
  err.code = 400;
  // forward control on to the next registered error handler:
  return next(err);
}

इरेटास्टस = 400; मैं अधिक आम है।
एमकेमेलिन

11

आप इसे इस तरह से उपयोग कर सकते हैं

return res.status(400).json({'error':'User already exists.'});

3

मेरा उपयोग-मामला कस्टम JSON त्रुटि संदेश भेज रहा है, क्योंकि मैं अपने REST API को शक्ति के लिए उपयोग कर रहा हूं। मुझे लगता है कि यह काफी सामान्य परिदृश्य है, इसलिए मेरे जवाब में इस पर ध्यान दिया जाएगा।

लघु संस्करण:

एक्सप्रेस त्रुटि से निपटने

तीन के बजाय चार तर्कों को छोड़कर अन्य मिडलवेयर की तरह त्रुटि से निपटने वाले मिडलवेयर को परिभाषित करें, विशेष रूप से हस्ताक्षर (इरेट, रीक, रेस, नेक्स्ट) के साथ। ... आप अन्य app.use () और मार्गों कॉल के बाद, त्रुटि से निपटने वाले मिडलवेयर को परिभाषित करते हैं

app.use(function(err, req, res, next) {
    if (err instanceof JSONError) {
      res.status(err.status).json({
        status: err.status,
        message: err.message
      });
    } else {
      next(err);
    }
  });

कोड के किसी भी बिंदु से त्रुटियों को उठाएं:

var JSONError = require('./JSONError');
var err = new JSONError(404, 'Uh oh! Can't find something');
next(err);

दीर्घ संस्करण

त्रुटि फेंकने का विहित तरीका है:

var err = new Error("Uh oh! Can't find something");
err.status = 404;
next(err)

डिफ़ॉल्ट रूप से, एक्सप्रेस इसे संभालकर बड़े करीने से इसे 404 कोड के साथ HTTP रिस्पॉन्स के रूप में पैकेजिंग करता है, और स्टैक ट्रेस के साथ संलग्न संदेश स्ट्रिंग से मिलकर शरीर।

यह मेरे लिए तब काम नहीं करता है जब मैं एक्सप्रेस का उपयोग REST सर्वर के रूप में कर रहा हूं, उदाहरण के लिए। मैं चाहता हूँ कि त्रुटि HTML के रूप में नहीं, JSON के रूप में वापस भेजी जाए। मैं निश्चित रूप से मेरे स्टैक ट्रेस को अपने क्लाइंट के लिए नहीं ले जाना चाहता।

मैं JSON का उपयोग करके एक प्रतिक्रिया के रूप में भेज सकता हूं req.json(), जैसे। की तरह कुछ req.json({ status: 404, message: 'Uh oh! Can't find something'})। वैकल्पिक रूप से, मैं स्थिति कोड का उपयोग करके सेट कर सकता हूं req.status()। दो का मेल:

req.status(404).json({ status: 404, message: 'Uh oh! Can't find something'});

यह एक आकर्षण की तरह काम करता है। उस ने कहा, मुझे हर बार टाइप करने में काफी अस्वाभाविक लगता है, और कोड हमारे जैसा नहीं next(err)था। यह एक सामान्य (यानी, मान्य) प्रतिक्रिया JSON को कैसे भेजा जाता है, इसके समान है। इसके अलावा, विहित दृष्टिकोण द्वारा फेंकी गई किसी भी त्रुटि का परिणाम अभी भी HTML आउटपुट में है।

यह वह जगह है जहां मिडलवेयर से निपटने में एक्सप्रेस की त्रुटि आती है। मेरे मार्गों के हिस्से के रूप में, मैं परिभाषित करता हूं:

app.use(function(err, req, res, next) {
    console.log('Someone tried to throw an error response');
  });

मैं भी एक कस्टम JSONError वर्ग में त्रुटि उपवर्ग:

JSONError = function (status, message) {
    Error.prototype.constructor.call(this, status + ': ' + message);
    this.status = status;
    this.message = message;
  };
JSONError.prototype = Object.create(Error);
JSONError.prototype.constructor = JSONError;

अब, जब मैं कोड में एक त्रुटि फेंकना चाहता हूँ, मैं करता हूँ:

var err = new JSONError(404, 'Uh oh! Can't find something');
next(err);

मिडिलवेयर को संभालने वाली कस्टम त्रुटि पर वापस जाकर, मैं इसे संशोधित करता हूं:

app.use(function(err, req, res, next) {
  if (err instanceof JSONError) {
    res.status(err.status).json({
      status: err.status,
      message: err.message
    });
  } else {
    next(err);
  }
}

JSONError में सबक्लासिंग एरर महत्वपूर्ण है, क्योंकि मुझे संदेह है कि एक सामान्य हैंडलर या एक एरर हैंडलर को लागू करने के लिए यह निर्धारित करने के instanceof Errorलिए एक्सप्रेस पहले पैरामीटर पर एक चेक करता है next()। मैं instanceof JSONErrorचेक को हटा सकता हूं और अप्रत्याशित त्रुटियां (जैसे कि दुर्घटना) सुनिश्चित करने के लिए मामूली संशोधन भी कर सकता हूं, जो JSON प्रतिक्रिया देता है।


2

Axios का उपयोग करते समय आप निम्न प्रतिक्रिया संदेश को पुनः प्राप्त कर सकते हैं:

Axios.get(“your_url”)
.then(data => {
... do something
}.catch( err => {
console.log(err.response.data) // you want this
})

... इसे एक्सप्रेस में स्थापित करने के बाद:

res.status(400).send(“your custom message”)

0

यदि आपका लक्ष्य इसे एक एकल / सरल रेखा तक कम करना है, तो आप थोड़ा सा चूक पर भरोसा कर सकते हैं ...

return res.end(res.writeHead(400, 'Current password does not match'));

-2

वैसे रेस्टोर के मामले में हमें sendRaw()विधि का उपयोग करना चाहिए

सिंटैक्स है: res.sendRaw(200, 'Operation was Successful', <some Header Data> or null)

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