本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
CloudFront Functions 事件結構
CloudFront Functions 在運行該函數時將 event
物件作為輸入傳遞給您的函數程式碼。測試函數時,建立 event
物件並將其傳遞給函數。建立用於測試函數的 event
物件時,您可以省略 distributionDomainName
物件中的 distributionId
、requestId
和 context
欄位。此外,請確保標頭名稱為小寫,CloudFront Functions 在生產期間傳遞給函數的 event
物件中也會始終採用此形式。
以下是此事件物件結構的概觀。
{ "version": "1.0", "context": { <context object> }, "viewer": { <viewer object> }, "request": { <request object> }, "response": { <response object> } }
如需詳細資訊,請參閱下列主題:
版本欄位
version
欄位包含指定 CloudFront Functions 事件物件版本的字串。目前版本是 1.0
。
內容物件
context
物件包含有關事件的關聯式資訊。它包括以下欄位:
distributionDomainName
-
與事件相關聯之標準分佈的 CloudFront 網域名稱 (例如 d111111abcdef8.cloudfront.net)。
只有當您的函數被叫用標準分佈時,
distributionDomainName
欄位才會出現。 endpoint
-
與事件相關聯之連線群組的 CloudFront 網域名稱 (例如 d111111abcdef8.cloudfront.net)。
只有當您的函數被叫用進行多租用戶分佈時,
endpoint
欄位才會出現。 distributionId
-
與事件相關聯的發佈的 ID (例如 EDFDVBD6EXAMPLE)。
eventType
-
事件類型,
viewer-request
或viewer-response
。 requestId
-
唯一識別 CloudFront 請求 (及其相關回應) 的字串。
檢視者物件
viewer
物件包含一個 ip
欄位,其值是傳送請求的檢視者 (用戶端) 的 IP 地址。如果檢視者的請求來自 HTTP 代理或負載平衡器,此值為代理或負載平衡器的 IP 地址。
請求物件
request
物件包含檢視者到 CloudFront HTTP 請求的表示。在傳遞給函數的 event
物件中,request
物件代表 CloudFront 從檢視者接收的實際請求。
如果您的函數程式碼將 request
物件返回到 CloudFront,其必須使用相同的結構。
request
物件包含下列欄位:
method
-
請求的 HTTP 方法。如果您的函數程式碼傳回
request
,則無法修改此欄位。這是request
物件中唯一的唯讀欄位。 uri
-
請求物件的相對路徑。
注意
如果您的函數修改
uri
值,則適用下列條件:-
全新的
uri
值必須以正斜線 (/
) 作為開頭。 -
當函數變更
uri
值時,它會變更檢視者請求的物件。 -
當函數變更
uri
值時,它不會變更請求的快取行為或原始伺服器請求傳送的來源。
-
querystring
-
代表請求中的查詢字串的物件。如果請求不包含查詢字串,
request
物件仍會包含空白的querystring
物件。querystring
物件針對請求中的每個查詢字串參數包含一個欄位。 headers
-
代表請求中 HTTP 標頭的物件。如果請求包含任何
Cookie
標頭,則這些標頭不是headers
物件的一部分。Cookies 在cookies
物件中單獨表示。headers
物件針對請求中的每個標頭包含一個欄位。在事件物件中,標頭名稱會轉換為 ASCII 小寫,而且當您的函數程式碼新增標頭名稱時,標頭名稱必須是 ASCII 小寫。當 CloudFront Functions 將事件物件轉換回 HTTP 請求時,如果標頭名稱中每個單字的第一個字母是 ASCII 字母,則會大寫。CloudFront Functions 不會將任何變更套用至標頭名稱中的非 ASCII 符號。例如,TÈst-header
將進入 函數tÈst-header
。非 ASCII 符號È
保持不變。單字以連字號分隔 (
-
)。例如,如果函數程式碼新增名為example-header-name
的標頭,CloudFront 會將其轉換為 HTTP 請求中的Example-Header-Name
。 cookies
-
代表請求 (
Cookie
標頭) 中 Cookie 的物件。cookies
物件針對請求中的每個 Cookie 包含一個欄位。
如需有關查詢字串、標頭和 Cookie 結構的詳細資訊,請參閱 查詢字串、標頭和 Cookie 的結構。
如需範例 event
物件,請參閱 範例事件物件。
回應物件
response
物件包含 CloudFront 到檢視者的 HTTP 回應的表示。在傳遞給函數的 event
物件中,response
物件代表 CloudFront 對檢視者請求的實際回應。
如果您的函數程式碼返回 response
物件,其必須使用相同的結構。
response
物件包含下列欄位:
statusCode
-
回應的 HTTP 狀態碼。該值是一個整數,而不是字串。
您的函數可以產生或修改
statusCode
。 statusDescription
-
回應的 HTTP 狀態說明。如果您的函數程式碼產生回應,則此欄位為選用。
headers
-
代表回應中 HTTP 標頭的物件。如果回應包含任何
Set-Cookie
標頭,則這些標頭不是headers
物件的一部分。Cookies 在cookies
物件中單獨表示。headers
物件針對回應中的每個標頭包含一個欄位。在事件物件中,標頭名稱會轉換為小寫,而在函數程式碼新增標頭名稱時,標頭名稱必須是小寫。當 CloudFront Functions 將事件物件轉換回 HTTP 回應時,標頭名稱中每個單字的第一個字母會大寫。單字以連字號分隔 (-
)。例如,如果函數程式碼新增名為example-header-name
的標頭,CloudFront 會將其轉換為 HTTP 回應中的Example-Header-Name
。 cookies
-
代表回應 (
Set-Cookie
標頭) 中 Cookie 的物件。cookies
物件針對回應中的每個 Cookie 包含一個欄位。 body
-
新增
body
欄位是選擇性的,除非您在函數中進行指定,否則它不會出現在response
物件中。您的函數無法存取 CloudFront 快取或原始伺服器傳回的原始本文。如果您未在檢視器回應函數中指定body
欄位,則 CloudFront 快取或原始伺服器回傳的原始本文將傳回給檢視器。如果您希望 CloudFront 將自訂本文傳回給檢視器,請在
data
欄位中指定本文內容,並在encoding
欄位中指定本文編碼。您可以將編碼指定為純文字 ("encoding": "text"
) 或 Base64 編碼的內容 ("encoding": "base64"
)。作為捷徑,您也可以直接在
body
欄位 ("body": "<specify the body content here>"
) 中指定本文內容。執行此操作時,請省略data
和encoding
欄位。在這種情況下,CloudFront 會將本文視為純文字。encoding
-
body
內容 (data
欄位) 的編碼。唯一的有效編碼是text
和base64
。如果您將
encoding
指定為base64
但本文不是有效的 base64,CloudFront 會傳回錯誤。 data
-
body
內容。
如需有關已修改狀態碼和本文內容的更多資訊,請參閱 狀態碼和本文。
如需有關標頭和 Cookie 結構的詳細資訊,請參閱 查詢字串、標頭和 Cookie 的結構。
如需範例 response
物件,請參閱 範例回應物件。
狀態碼和本文
透過 CloudFront Functions,您可以更新檢視者回應本文或將其移除。在評估來自 CloudFront 快取或原始伺服器回應的各個層面後,更新檢視器回應的一些常見案例包括:
-
變更狀態以設定 HTTP 200 狀態碼並建立靜態本文內容,以傳回給檢視器。
-
變更狀態以設定 HTTP 301 或 302 狀態碼來重新導向使用者到另一個網站。
-
決定是否要提供或捨棄檢視者回應的本文。
注意
如果原始伺服器傳回 400 及以上的 HTTP 錯誤,CloudFront Function 將無法執行。如需更多資訊,請參閱對所有邊緣函數的限制。
在您使用 HTTP 回應時,CloudFront Functions 將無法存取回應本文。您可以透過將本文內容設定為所需的值來進行替換,或設定為空值來移除本文。如果您不更新函數中的本文欄位,CloudFront 快取或原始伺服器回傳的原始本文會傳回給檢視器。
提示
使用 CloudFront Functions 取代本文時,請務必將對應的標頭 (例如 content-encoding
、content-type
或 content-length
) 對齊新的本文內容。
例如,如果 CloudFront 原始伺服器或快取傳回 content-encoding:
gzip
,但檢視器回應函數設定了純文字的本文,則該函數也需要相應變更 content-encoding
和 content-type
標頭。
如果您的 CloudFront Function 設定為傳回 400 或更高的 HTTP 錯誤,您的檢視者將不會看到您為相同狀態碼指定的自訂錯誤頁面。
查詢字串、標頭和 Cookie 的結構
查詢字串、標頭和 Cookie 共用相同的結構。查詢字串可能會出現在請求中。標頭會出現在請求和回應中。Cookie 會出現在請求和回應中。
每個查詢字串、標頭或 Cookie 都是父系 querystring
、headers
或 cookies
物件中的唯一欄位。欄位名稱是查詢字串、標頭或 Cookie 的名稱。每個欄位都包含具有查詢字串、標頭或 Cookie 值的 value
屬性。
查詢字串值或查詢字串物件
除了查詢字串物件之外,函數還可以傳回查詢字串值。查詢字串值可用來依任意自訂順序排列查詢字串參數。
範例
若要修改函數程式碼中的查詢字串,請使用如下所示的程式碼。
var request = event.request; request.querystring = 'ID=42&Exp=1619740800&TTL=1440&NoValue=&querymv=val1&querymv=val2,val3';
標頭的特殊考量
僅針對標頭,標頭名稱會在事件物件中轉換為小寫,而在函數程式碼新增標頭名稱時,標頭名稱則必須是小寫。當 CloudFront Functions 將事件物件轉換回 HTTP 請求或回應時,標頭名稱中每個單字的第一個字母會大寫。單字以連字號分隔 (-
)。例如,如果函數程式碼新增名為 example-header-name
的標題,CloudFront 會將其轉換為 HTTP 請求或回應中的 Example-Header-Name
。
範例
請考慮 HTTP 請求中的下列Host
標頭。
Host: video.example.com
此標頭在 request
物件中的表示方式如下:
"headers": { "host": { "value": "video.example.com" } }
若要在函數程式碼中存取 Host
標頭,請使用如下所示的程式碼:
var request = event.request; var host = request.headers.host.value;
若要在函數程式碼中新增或修改標頭,請使用如下所示的程式碼 (此程式碼會新增名為 X-Custom-Header
且包含值 example value
的標頭):
var request = event.request; request.headers['x-custom-header'] = {value: 'example value'};
重複的查詢字串、標頭和 Cookie (multiValue
陣列)
HTTP 請求或回應可以包含多個具有相同名稱的查詢字串、標頭或 Cookie。在此情況下,重複的查詢字串、標頭或 Cookie 會折疊成 request
或 response
物件中的一個欄位,但此欄位包含一個名為 multiValue
的額外屬性。multiValue
屬性包含一個陣列,其中帶有每個重複查詢字串、標頭或 Cookie 的值。
範例
考慮具有下列Accept
標頭的 HTTP 請求。
Accept: application/json Accept: application/xml Accept: text/html
這些標頭在 request
物件中如下所示。
"headers": { "accept": { "value": "application/json", "multiValue": [ { "value": "application/json" }, { "value": "application/xml" }, { "value": "text/html" } ] } }
注意
第一個標頭值 (在此案例中為 application/json
) 會在 value
和 multiValue
屬性中重複。這可讓您透過在 multiValue
陣列中執行迴圈來存取所有值。
如果您的函數程式碼修改具有 multiValue
陣列的查詢字串、標頭或 Cookie,CloudFront Functions 會使用下列規則來套用變更:
-
如果
multiValue
陣列存在且有任何修改,則套用此修改。value
屬性中的第一個元素被忽略。 -
否則,會套用
value
屬性的任何修改,並且後續的值 (如果存在) 保持不變。
只有當 HTTP 請求或回應包含具有相同名稱的重複查詢字串、標頭或 Cookie 時,才會使用 multiValue
屬性,如上述範例所示。但是,如果單一查詢字串、標頭或 Cookie 中有多個值,則不會使用該 multiValue
屬性。
範例
考慮具有一個Accept
標頭的請求,其中包含三個值。
Accept: application/json, application/xml, text/html
此標頭在 request
物件中如下所示。
"headers": { "accept": { "value": "application/json, application/xml, text/html" } }
Cookie 屬性
在 HTTP 回應的 Set-Cookie
標頭中,標頭包含 Cookie 的名稱/值對,以及選用的一組屬性 (以分號分隔)。
範例
Set-Cookie: cookie1=val1; Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT
在 response
物件中,這些屬性會在 Cookie 欄位的 attributes
屬性中表示。例如,前面的 Set-Cookie
標頭表示如下:
"cookie1": { "value": "val1", "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT" }
範例回應物件
以下範例顯示一個本文已被檢視器回應函數替換的 response
物件 (檢視器回應函數的輸出)。
{ "response": { "statusCode": 200, "statusDescription": "OK", "headers": { "date": { "value": "Mon, 04 Apr 2021 18:57:56 GMT" }, "server": { "value": "gunicorn/19.9.0" }, "access-control-allow-origin": { "value": "*" }, "access-control-allow-credentials": { "value": "true" }, "content-type": { "value": "text/html" }, "content-length": { "value": "86" } }, "cookies": { "ID": { "value": "id1234", "attributes": "Expires=Wed, 05 Apr 2021 07:28:00 GMT" }, "Cookie1": { "value": "val1", "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT", "multiValue": [ { "value": "val1", "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT" }, { "value": "val2", "attributes": "Path=/cat; Domain=example.com; Expires=Wed, 10 Jan 2021 07:28:00 GMT" } ] } }, // Adding the body field is optional and it will not be present in the response object // unless you specify it in your function. // Your function does not have access to the original body returned by the CloudFront // cache or origin. // If you don't specify the body field in your viewer response function, the original // body returned by the CloudFront cache or origin is returned to viewer. "body": { "encoding": "text", "data": "<!DOCTYPE html><html><body><p>Here is your custom content.</p></body></html>" } } }
範例事件物件
以下範例顯示完整的 event
物件。這是標準分佈的範例調用,而不是多租用戶分佈。對於多租戶分佈,使用 endpoint
欄位,而不是 distributionDomainName
的值endpoint
是與事件相關聯之連線群組的 CloudFront 網域名稱 (例如 d111111abcdef8.cloudfront.net)。
注意
event
物件是函數的輸入。您的函數僅返回 request
或 response
物件,而不是完整的 event
物件。
{ "version": "1.0", "context": { "distributionDomainName": "d111111abcdef8.cloudfront.net", "distributionId": "EDFDVBD6EXAMPLE", "eventType": "viewer-response", "requestId": "EXAMPLEntjQpEXAMPLE_SG5Z-EXAMPLEPmPfEXAMPLEu3EqEXAMPLE==" }, "viewer": {"ip": "198.51.100.11"}, "request": { "method": "GET", "uri": "/media/index.mpd", "querystring": { "ID": {"value": "42"}, "Exp": {"value": "1619740800"}, "TTL": {"value": "1440"}, "NoValue": {"value": ""}, "querymv": { "value": "val1", "multiValue": [ {"value": "val1"}, {"value": "val2,val3"} ] } }, "headers": { "host": {"value": "video.example.com"}, "user-agent": {"value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0"}, "accept": { "value": "application/json", "multiValue": [ {"value": "application/json"}, {"value": "application/xml"}, {"value": "text/html"} ] }, "accept-language": {"value": "en-GB,en;q=0.5"}, "accept-encoding": {"value": "gzip, deflate, br"}, "origin": {"value": "https://website.example.com"}, "referer": {"value": "https://website.example.com/videos/12345678?action=play"}, "cloudfront-viewer-country": {"value": "GB"} }, "cookies": { "Cookie1": {"value": "value1"}, "Cookie2": {"value": "value2"}, "cookie_consent": {"value": "true"}, "cookiemv": { "value": "value3", "multiValue": [ {"value": "value3"}, {"value": "value4"} ] } } }, "response": { "statusCode": 200, "statusDescription": "OK", "headers": { "date": {"value": "Mon, 04 Apr 2021 18:57:56 GMT"}, "server": {"value": "gunicorn/19.9.0"}, "access-control-allow-origin": {"value": "*"}, "access-control-allow-credentials": {"value": "true"}, "content-type": {"value": "application/json"}, "content-length": {"value": "701"} }, "cookies": { "ID": { "value": "id1234", "attributes": "Expires=Wed, 05 Apr 2021 07:28:00 GMT" }, "Cookie1": { "value": "val1", "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT", "multiValue": [ { "value": "val1", "attributes": "Secure; Path=/; Domain=example.com; Expires=Wed, 05 Apr 2021 07:28:00 GMT" }, { "value": "val2", "attributes": "Path=/cat; Domain=example.com; Expires=Wed, 10 Jan 2021 07:28:00 GMT" } ] } } } }