2017-08-16 234 views
4

我試圖按照指示在這裏https://medium.com/@tom.cook/edge-lambda-cloudfront-custom-headers-3d134a2c18a2lambda函數返回的無效請求或響應CloudFront的

我CloudFront的成功坐在靜態S3前面的「Hello World」的HTML文件,我想設置使用lambda邊緣的其他標題,但我得到一個錯誤。真正令人沮喪的是,我找不到任何錯誤日誌來調試出錯。這是瀏覽器顯示的內容。

ERROR 

The request could not be satisfied. 

The Lambda function returned an invalid request or response to CloudFront. 
Generated by cloudfront (CloudFront) 
Request ID: 2Cqex7euzH0Iigps58i9tMVxdqAaLznL2ZjwqR1sW1AZHz6x2EwfMA== 

這裏是我的簡單的λ代碼:

exports.handler = (event, context, callback) => { 
    console.log(event) 
    callback(null, 'Hello from Lambda'); 
}; 

觸發類型爲viewer-response,並連接到我的CloudFront的分佈(與Cache Behavior: *,如果該事項)。該lambda具有對應於AWSLambdaBasicExecutionRole的角色,該角色提供對Cloudwatch的寫入訪問權限。

只要啓用觸發器,對Web請求的響應就會從我的「Hello world」HTML更改爲上述錯誤,所以我知道它正在觸發lambda。但在lambda儀表板中,它沒有顯示任何調用或錯誤。 Cloudwatch中沒有日誌。 CloudFront儀表板顯示錯誤(5xx),但沒有任何來自lambda的。

如果我然後通過單擊部署函數,將測試事件配置爲「CloudFront修改響應頭」,然後敲擊測試,在lambda控制檯內測試我的函數,它會成功。 Cloudwatch顯示測試的日誌和控制檯輸出!但是實時調用的日誌仍然沒有。

我唯一的理論是權限有問題,CloudFront實際上無法調用lambda(解釋爲什麼lambda儀表板中沒有任何內容)。最後一件事是CloudFront日誌(在S3中)顯示了帶有502錯誤和LambdaValidationError的Web請求,但我無法弄清楚這是否有幫助。

+0

如果我下面的回答無法解決您的問題,請將您的代碼壓縮到[MCVE](https://stackoverflow.com/help/mcve)並將其編輯到問題中。 –

+1

你的答案確實解決了我的問題,@sqlbot。我仍然擔心的是,當我改變我的功能時,我無法每次都運行它們!我的例子中的問題是返回一個字符串,但是我怎麼能從CF和Lambda生成的錯誤/日誌中知道? – lordbyron

+0

呃,你知道的......只要你有一個資金充足的PayPal帳戶,你可以隨時運行它們。 :)儘管如此,您是對的 - 您無法知道,因爲當沒有節點錯誤但CloudFront拒絕Lambda響應時,日誌無法繼續,當然也不會將錯誤返回給瀏覽器是一種很好的做法。但是在文檔和例子之間,沒有任何東西無法通過。一定要看看所有的「藍圖」。它們生成的格式與CloudFront喜歡的格式完全相同。 –

回答

4

您正在查看的博客文章中的示例有效,而Lambda @ Edge仍處於預覽狀態(在啓動之前對特定客戶的訪問權限有限),但它不再正確。在服務啓動之前不久,數據結構發生了變化。

的響應報頭數據結構以前是這樣的:

headers['Strict-Transport-Security'] = "max-age=31536000; includeSubdomains; preload"; 
headers['Content-Security-Policy'] = "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'"; 
headers['X-Content-Type-Options'] = "nosniff"; 

的新的結構是這樣的:

headers['strict-transport-security'] = [{ 
    key: 'Strict-Transport-Security', 
    value: "max-age=31536000; includeSubdomains; preload" 
}]; 

headers['content-security-policy'] = [{ 
    key: 'Content-Security-Policy', 
    value: "default-src 'none'; img-src 'self'; script-src 'self'; style-src 'self'; object-src 'none'" 
}]; 

headers['x-content-type-options'] = [{ 
    key: 'X-Content-Type-Options', 
    value: "nosniff" 
}]; 

在外部對象的密鑰必須是key值的小寫等效在內部物體的每個成員中。爲了更加準確地反映HTTP頭文件的處理方式,最需要對數據結構進行更改,因爲在HTTP/1.x中它們不區分大小寫,但在JavaScript對象中,這些密鑰區分大小寫。

如果您的代碼返回的結構不符合CloudFront要求Lambda @ Edge返回的結果,那麼您看到的錯誤確實會被拋出。沒有生成日誌,因爲日誌沒有放置位置 - 此錯誤發生在Lambda之外,Lambda和CloudFront之間的界面邊界的CloudFront側,它不會生成任何用戶可訪問的日誌。

請參閱Response Event Structure的文檔。

+0

使用@ michael-sqlbot在AWS論壇中繼續執行此主題https://forums.aws.amazon.com/thread.jspa?messageID=800313#800313 – lordbyron

+0

根據新規範修復響應事件結構爲我解決了問題http ://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html –

+0

我仍然無法得到這個工作。任何人發現問題? –