本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
CloudFront 函數事件結構
CloudFront 函數會在執行函數時,將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)。
distributionId
-
與事件相關聯的發佈的 ID (例如 EDFDVBD6EXAMPLE)。
eventType
-
事件類型,
viewer-request
或viewer-response
。 requestId
-
唯一識別 CloudFront 要求 (及其相關回應) 的字串。
檢視者物件
viewer
物件包含一個 ip
欄位,其值是傳送請求的檢視者 (用戶端) 的 IP 地址。如果檢視者的請求來自 HTTP 代理或負載平衡器,此值為代理或負載平衡器的 IP 地址。
請求物件
該request
對象包含查看器對 HTTP 請求的表示。CloudFront 在傳遞給函數的event
對象中,該request
對象表示從查看器 CloudFront 收到的實際請求。
如果您的函數代碼返回一個request
對象 CloudFront,它必須使用相同的結構。
request
物件包含下列欄位:
method
-
請求的 HTTP 方法。如果您的函數代碼返回 a
request
,則無法修改此字段。這是request
物件中唯一的唯讀欄位。 uri
-
請求物件的相對路徑。
注意
如果您的函數修改了
uri
值,則適用以下內容:-
全新的
uri
值必須以正斜線 (/
) 作為開頭。 -
當函數變更
uri
值時,它會變更檢視者請求的物件。 -
當函數變更
uri
值時,它不會變更請求的快取行為或原始伺服器請求傳送的來源。
-
querystring
-
代表請求中的查詢字串的物件。如果請求不包含查詢字串,
request
物件仍會包含空白的querystring
物件。querystring
物件針對請求中的每個查詢字串參數包含一個欄位。 headers
-
代表請求中 HTTP 標頭的物件。如果請求包含任何
Cookie
標頭,則這些標頭不是headers
物件的一部分。Cookies 在cookies
物件中單獨表示。headers
物件針對請求中的每個標頭包含一個欄位。在事件物件中,標頭名稱會轉換為小寫,而在函數程式碼新增標頭名稱時,標頭名稱必須是小寫。當 CloudFront Functions 將事件物件轉換回 HTTP 要求時,標頭名稱中每個單字的第一個字母都會大寫。單字以連字號分隔 (-
)。例如,如果您的函數代碼添加了一個名為的標頭example-header-name
,請在 HTTP 請求Example-Header-Name
中將其 CloudFront 轉換為。 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
,請在 HTTP 響應Example-Header-Name
中將其 CloudFront 轉換為。 cookies
-
代表回應 (
Set-Cookie
標頭) 中 Cookie 的物件。cookies
物件針對回應中的每個 Cookie 包含一個欄位。 body
-
新增
body
欄位是選擇性的,除非您在函數中進行指定,否則它不會出現在response
物件中。您的函數無法訪問 CloudFront緩存或 origin 返回的原始主體。如果您沒有在檢視器回應函式中指定body
欄位, CloudFront 快取或 origin 傳回的原始主體會傳回給檢視者。如果您想 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 函式將無法執行。如需更多資訊,請參閱對所有邊緣函數的限制。
當您使用 HTTP 響應時, CloudFront 函數無法訪問響應主體。您可以透過將本文內容設定為所需的值來進行替換,或設定為空值來移除本文。如果您不更新函數中的 body 字段,則 CloudFront 緩存或 origin 返回的原始主體將返回給查看者。
提示
使用 CloudFront Functions 來取代主體時,請務必將對應的標題 (例如content-encoding
、content-type
content-length
、或) 對齊新的本文內容。
例如,如果 CloudFront 原點或緩存返回,content-encoding:
gzip
但查看器響應函數設置了純文本的主體,該函數也需要相應地更改content-encoding
和content-type
標題。
如果您的 CloudFront 函數配置為返回 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
,請Example-Header-Name
在 HTTP 請求或響應中將其 CloudFront 轉換為。
範例
請在 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" } ] } }
注意
在value
和multiValue
屬性中會重複第一個標頭值 (在本例中為application/json
)。這可讓您透過在 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
物件。
注意
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" } ] } } } }