AWS लैम्ब्डा एपीआई गेटवे त्रुटि "विकृत लाम्बा प्रॉक्सी प्रतिक्रिया"


84

मैं AWS लैंबडा के साथ एक हैलो दुनिया उदाहरण स्थापित करने और एपीआई गेटवे के माध्यम से सेवा करने की कोशिश कर रहा हूं। मैंने "क्रिएट ए लैंबडा फंक्शन" पर क्लिक किया, जिसने एपी गेटवे को स्थापित किया और ब्लैंक फंक्शन विकल्प का चयन किया। मैंने एडब्ल्यूएस गेटवे पर मिलने वाले लंबो फंक्शन को गाइड करना शुरू किया :

exports.handler = function(event, context, callback) {
  callback(null, {"Hello":"World"});  // SUCCESS with message
};

मुद्दा यह है कि जब मैं इसे GET अनुरोध करता हूं, तो यह 502 प्रतिसाद वापस कर रहा है { "message": "Internal server error" }। और लॉग कहते हैं "कॉन्फ़िगरेशन त्रुटि के कारण निष्पादन विफल हो गया: विकृत लाम्बा प्रॉक्सी प्रतिक्रिया"।

जवाबों:


112

आमतौर पर, जब आप देखते हैं Malformed Lambda proxy response, तो इसका मतलब है कि आपके लैम्ब्डा फ़ंक्शन से आपकी प्रतिक्रिया प्रारूप से मेल नहीं खाती है। एपीआई गेटवे इस तरह की अपेक्षा कर रहा है

{
    "isBase64Encoded": true|false,
    "statusCode": httpStatusCode,
    "headers": { "headerName": "headerValue", ... },
    "body": "..."
}

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

इसके अलावा, यदि आप रुक-रुक कर देख रहे हैं, तो Malformed Lambda proxy responseइसका मतलब यह हो सकता है कि आपके लाम्बा समारोह का अनुरोध लैंबडा द्वारा किया गया है, और आपको लैम्ब्डा फ़ंक्शन पर समवर्ती निष्पादन सीमा वृद्धि का अनुरोध करने की आवश्यकता है।



4
यहाँ इस पर एक एडब्ल्यूएस समर्थन लेख है: aws.amazon.com/premiumsupport/knowledge-center/…
craigmichaelmartin

यह उत्तर वास्तव में मददगार था। धन्यवाद!
वलेड93

49

यदि लंबो को प्रॉक्सी के रूप में उपयोग किया जाता है, तो प्रतिक्रिया प्रारूप होना चाहिए

{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"body": "..."
}

नोट: शरीर कड़ा होना चाहिए


यदि JSON.stringify (प्रतिक्रिया) काम नहीं करता है तो "प्रतिक्रिया" आपकी वस्तु का नाम है। इसे इस तरह छोड़कर मेरे लिए काम किया। callback(null,response);
नियो

4
@ अब आपको प्रतिक्रिया ऑब्जेक्ट को सख्त करने की आवश्यकता नहीं है। आप प्रतिक्रिया वस्तु के शरीर की कुंजी के अंदर डेटा को
सख्त

जिज्ञासा से बाहर - शरीर को कठोर करने की आवश्यकता क्यों है? यह एक ऐसी चीज पर मेरा मुद्दा था जिस पर मैं काम कर रहा था, और इसकी वजह से मुझे भ्रम हुआ - धन्यवाद
andy mccullough

2
इनमें से, statusCodeएपीआई गेटवे से सफल होने के लिए केवल एक कॉल की आवश्यकता होती है।
ट्रेंटन

यह सुनिश्चित करना कि शरीर मेरे लिए कठोर है। बहुत बहुत धन्यवाद +1
किमुताई

26

हाँ तो मुझे लगता है कि यह इसलिए है क्योंकि आप वास्तव में एक उचित http प्रतिक्रिया नहीं दे रहे हैं, यही वजह है कि आपको त्रुटि मिल रही है।

व्यक्तिगत रूप से मैं इस तरह के कार्यों का एक सेट का उपयोग करता हूं:

    module.exports = {
        success: (result) => {
            return {
                statusCode: 200,
                headers: {
                    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
                    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
                },
                body: JSON.stringify(result),
            }
        },
        internalServerError: (msg) => {
            return {
                statusCode: 500,
                headers: {
                    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
                    "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
                },
                body: JSON.stringify({
                    statusCode: 500,
                    error: 'Internal Server Error',
                    internalError: JSON.stringify(msg),
                }),
            }
        }
} // add more responses here.

तो फिर तुम बस करो:

var responder = require('responder')

// some code

callback(null, responder.success({ message: 'hello world'}))

अब, यदि हम Access-Control-Allow-Credentials वैल्यू को सही मानते हैं, तो हम 'Access-Control-
allow

1
मैंने देखा कि यह केवल एक उत्पत्ति का समर्थन करता है: हेडर: {"एक्सेस-कंट्रोल-एलाउंस-ओरिजिन": "<< एकल डोमेन >>", "एक्सेस-कंट्रोल-कंट्रोल-अलाउड-क्रेडेंशियल्स": सच // कुकीज़ के लिए आवश्यक, प्राधिकरण हेडर HTTPS},
संतोष नागुलानी

6

से एडब्ल्यूएस डॉक्स

Node.js में एक लैम्ब्डा फ़ंक्शन में, एक सफल प्रतिक्रिया देने के लिए, कॉलबैक (अशक्त, {"स्टेटसकोड": 200, "बॉडी": "परिणाम"}) कॉल करें। एक अपवाद फेंकने के लिए, कॉलबैक (नई त्रुटि ('आंतरिक सर्वर त्रुटि'))। क्लाइंट-साइड त्रुटि के लिए, उदाहरण के लिए, एक आवश्यक पैरामीटर गायब है, आप कॉलबैक (अशक्त, {"स्टेटसकोड": 400, "बॉडी": "मिसिंग पैरामीटर ऑफ ... ..."}) को बिना फेंक दिए त्रुटि वापस करने के लिए कॉल कर सकते हैं अपवाद।


5

पायथन 3 के लिए:

import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*'
        },
        'body': json.dumps({
            'success': True
        }),
        "isBase64Encoded": False
    }

नोट को bodyसेट करने की आवश्यकता नहीं है, यह सिर्फ खाली हो सकता है:

        'body': ''

3

एक बहुत ही विशेष मामला, यदि आप हेडर को सीधे पास करते हैं तो एक मौका है कि आपके पास यह हेडर है:

"set-cookie": [ "........" ]

लेकिन अमेज़न को इसकी आवश्यकता है:

"set-cookie": "[ \\"........\\" ]"


3

जब प्रतिक्रिया मान्य प्रतीत होती है तो संघर्ष करने वाले किसी और के लिए। यह काम नहीं करता:

callback(null,JSON.stringify( {
  isBase64Encoded: false,
  statusCode: 200,
  headers: { 'headerName': 'headerValue' },
  body: 'hello world'
})

लेकिन यह करता है:

callback(null,JSON.stringify( {
  'isBase64Encoded': false,
  'statusCode': 200,
  'headers': { 'headerName': 'headerValue' },
  'body': 'hello world'
})

इसके अलावा, ऐसा प्रतीत होता है कि प्रतिक्रिया की वस्तु पर किसी अतिरिक्त कुंजी को उपस्थित होने की अनुमति नहीं है।


3

यदि आप https://github.com/aws/aws-lambda-go के साथ गो का उपयोग कर रहे हैं , तो आपको उपयोग करना होगा events.APIGatewayProxyResponse

func hello(ctx context.Context, event ImageEditorEvent) (events.APIGatewayProxyResponse, error) {
    return events.APIGatewayProxyResponse{
        IsBase64Encoded: false,
        StatusCode:      200,
        Headers:         headers,
        Body:            body,
    }, nil
}

3

मैंने उपरोक्त सभी सुझावों की कोशिश की है, लेकिन यह काम नहीं करता है जबकि bodyमूल्य नहीं हैString

return {
    statusCode: 200,
    headers: {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*"
    },
    body: JSON.stringify({
        success: true
    }),
    isBase64Encoded: false
};

3

.Net कोर और C # के लिए कोड का एक टुकड़ा :

using Amazon.Lambda.APIGatewayEvents;
...
var response = new APIGatewayProxyResponse
{
   StatusCode = (int)HttpStatusCode.OK,
   Body = JsonConvert.SerializeObject(new { msg = "Welcome to Belarus! :)" }),
   Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } }
};
return response;

लंबोदर से प्रतिक्रिया होगी:

{"statusCode":200,"headers":{"Content-Type":"application/json"},"multiValueHeaders":null,"body":"{\"msg\":\"Welcome to Belarus! :)\"}","isBase64Encoded":false}

एपी गेटवे से प्रतिक्रिया होगी:

{"msg":"Welcome to Belarus! :)"}

1
OMG, बहुत-बहुत धन्यवाद, आपने प्रतिक्रिया के दौरान हेडर कैसे प्राप्त करें, यह जानने की कोशिश करने के घंटों बाद ही मुझे बचाया। मैंने सादे JSON की कोशिश की, काम नहीं किया। मैंने मुख्य मूल्य जोड़े की कोशिश की, काम नहीं किया। शब्दकोश जाने का रास्ता था! धन्यवाद!
मिशा

1

मुझे यह त्रुटि थी क्योंकि मैंने गलती से CloudFormation AWS :: Serverless :: Api संसाधन से चर ServerlessExpressLambdaFunctionName हटा दिया था। यहाँ संदर्भ https://github.com/awslabs/aws-serverless-express "AWS लैंबडा और अमेज़ॅन एपीआई गेटवे के ऊपर, अपने मौजूदा Node.js एप्लिकेशन ढांचे का उपयोग करके सर्वर रहित एप्लिकेशन और REST API चलाएं"


0

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

मैं अपने फ़ंक्शन में एक RDS डेटाबेस को कॉल कर रहा था। यह पता चला कि जो समस्या पैदा हो रही थी, वह उस डेटाबेस पर सुरक्षा समूह के नियम (इनबाउंड) थे।

आप शायद उन IP पतों को प्रतिबंधित करना चाहते हैं जो एपीआई तक पहुँच प्राप्त कर सकते हैं, लेकिन यदि आप इसे जल्दी / गंदा काम करना चाहते हैं, तो यदि वह परिवर्तन ठीक कर देता है तो आप इसे सभी को स्वीकार करने के लिए सेट कर सकते हैं (आप भी सेट कर सकते हैं) सभी बंदरगाहों को भी स्वीकार करने के लिए बंदरगाहों पर रेंज, लेकिन मैंने इस उदाहरण में ऐसा नहीं किया):

यहाँ छवि विवरण दर्ज करें


0

"विकृत लैम्ब्डा प्रॉक्सी प्रतिक्रिया" त्रुटि का एक आम कारण है headersकि नहीं कर रहे हैं {String: String, ...}कुंजी / मान जोड़े।

चूंकि set-cookieहेडर और गुणकों में दिखाई देते हैं, वे के रूप में http.request.callback.response में प्रतिनिधित्व कर रहे हैं set-cookieएक होने कुंजी Arrayकी Strings एक के बजाय मूल्य एकलString । जबकि यह डेवलपर्स के लिए काम करता है, AWS API गेटवे इसे समझ नहीं पाता है और "विकृत लैम्ब्डा प्रॉक्सी प्रतिक्रिया" त्रुटि फेंकता है।

मेरा समाधान कुछ ऐसा करना है:

function createHeaders(headers) {
  const singleValueHeaders = {}
  const multiValueHeaders = {}
  Object.entries(headers).forEach(([key, value]) => {
    const targetHeaders = Array.isArray(value) ? multiValueHeaders : singleValueHeaders
    Object.assign(targetHeaders, { [key]: value })
  })

  return {
    headers: singleValueHeaders,
    multiValueHeaders,
  }
}

var output = {
  ...{
    "statusCode": response.statusCode,
    "body": responseString
  },
  ...createHeaders(response.headers)
}

ध्यान दें कि ...उपरोक्त का अर्थ यदा यदा यादा नहीं है । यह ES6 प्रसार ऑपरेटर है


0

यहाँ एक और दृष्टिकोण है। अपने एपीआई गेटवे एकीकरण अनुरोध और प्रतिक्रिया में मैपिंग टेम्पलेट को कॉन्फ़िगर करें। IntegrationRequest पर जाएं -> मैपिंगटेम्पलेट -> "जब कोई टेम्प्लेट परिभाषित न हों" का चयन करें -> सामग्री-प्रकार के लिए एप्लिकेशन / json टाइप करें। तो फिर तुम स्पष्ट रूप से एक json भेजने की जरूरत नहीं है। यहां तक ​​कि आपके ग्राहक को मिलने वाली प्रतिक्रिया भी एक सादे तार हो सकती है।


0

आपकी फ़ंक्शन प्रतिक्रिया का प्रारूप इस त्रुटि का स्रोत है। एपीआई गेटवे के लिए एक लैम्ब्डा फ़ंक्शन की प्रतिक्रिया को संभालने के लिए, प्रतिक्रिया इस प्रारूप में JSON होनी चाहिए:

{"BBase64Encoded ": सच | गलत," स्टेटसकोड ": httpStatusCode," हेडर ": {" हैडरनेम ":" हेडरवैल्यू ", ...}," बॉडी ":" ...}}

यहाँ सही ढंग से स्वरूपित प्रतिक्रिया के साथ Node.js में एक उदाहरण समारोह है:

Export.handler = (घटना, संदर्भ, कॉलबैक) => {

var responseBody = {
    "key3": "value3",
    "key2": "value2",
    "key1": "value1"
};

var response = {
    "statusCode": 200,
    "headers": {
        "my_header": "my_value"
    },
    "body": JSON.stringify(responseBody),
    "isBase64Encoded": false
};
callback(null, response);

};

Ref: https://aws.amazon.com/premiumsupport/knowledge-center/malformed-502-api-gateway/


0

अजगर 3.7

इससे पहले

{
    "isBase64Encoded": False,
    "statusCode": response.status_code,
    "headers": {
                  "Content-Type": "application/json",
               },
     "body": response.json()
}

उपरांत

{
    "isBase64Encoded": False,
    "statusCode": response.status_code,
    "headers": {
                  "Content-Type": "application/json",
               },
     "body": str(response.json()) //body must be of string type
}

0

यदि आप AWS के लिए नए हैं और बस अपना URL काम करना चाहते हैं,

यदि आपने अपने लैम्ब्डा फंक्शन के लिए ट्रिगर नहीं बनाया है, तो लैम्ब्डा फंक्शंस ऐप में फ़ंक्शन पर जाएं और एपीआई गेटवे का चयन करते हुए ट्रिगर बनाएं।

API गेटवे ऐप पर नेविगेट करें -> अपना विशेष लैम्ब्डा का एपीआई गेटवे (विधि निष्पादन) चुनें -> एकीकरण अनुरोध पर क्लिक करें -> "लैम्ब्डा प्रॉक्सी प्रॉक्सी का उपयोग करें" को अनचेक करें (चेक बॉक्स) ।

फिर " <-मैथोड एक्सक्यूशन " पर क्लिक करें और टेस्ट क्लाइंट सेक्शन पर क्लिक करें। विकल्प प्रदान करें और परीक्षण बटन पर क्लिक करें। आपको एक सफलता की प्रतिक्रिया देखनी चाहिए।

यदि आप अभी भी सफलता की प्रतिक्रिया प्राप्त करने में असमर्थ हैं, तो सही संस्करण के लिए एक उपनाम बनाएं (यदि आपके पास लैम्ब्डा फ़ंक्शन में कई संस्करण हैं)

लॉग से URL चुनें और अपने POST / GET टूल (Postman) का उपयोग करें और AWS हस्ताक्षर के रूप में प्रमाणीकरण चुनें - AWS क्षेत्र और सेवा के नाम के साथ डाकिया अनुरोध में अपनी प्रमाणीकरण कुंजियों (AccessKey & SecretKey) को लंबोदर के रूप में प्रदान करें।

पुनश्च: यह केवल शुरुआती लोगों की मदद कर सकता है और दूसरों के लिए अप्रासंगिक हो सकता है।

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