

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 呼叫 Lambda 函數 URL
<a name="urls-invocation"></a>

函數 URL 是 Lambda 函數專用的 HTTP(S) 端點。您可以透過 Lambda 主控台或 Lambda API 建立及設定函數 URL。

**提示**  
Lambda 提供兩種透過 HTTP 端點調用函式的方式：函式 URL 與 Amazon API Gateway。如果不確定哪種方法最適合自己的使用案例，請參閱[選取一種使用 HTTP 請求調用 Lambda 函數的方法](furls-http-invoke-decision.md)。

當您建立函數 URL 時，Lambda 會自動為您產生不重複的 URL 端點。函數 URL 一旦建立，其 URL 端點便永遠不會變更。函數 URL 端點的格式如下：

```
https://<url-id>.lambda-url.<region>.on.aws
```

**注意**  
下列 AWS 區域不支援函式 URL：亞太區域 (海德拉巴) (`ap-south-2`)、亞太區域 (墨爾本) (`ap-southeast-4`)、亞太區域 (馬來西亞) (`ap-southeast-5`)、亞太區域 (紐西蘭) (`ap-southeast-6`)、亞太區域 (泰國) (`ap-southeast-7`)、亞太區域 (台北) (`ap-east-2`)、加拿大西部 (卡加利)(`ca-west-1`)、歐洲 (西班牙) (`eu-south-2`)、歐洲 (蘇黎世) (`eu-central-2`)、以色列 (特拉維夫) (`il-central-1`) 以及中東 (阿拉伯聯合大公國) (`me-central-1`)。

函數 URL 可支援雙堆疊，能同時支援 IPv4 和 IPv6。設定函數 URL 後，您可以利用 Web 瀏覽器、curl、Postman 或任何 HTTP 用戶端，透過 HTTP(S) 端點呼叫函數。若要調用函式 URL，您必須擁有 `lambda:InvokeFunctionUrl` 和 `lambda:InvokeFunction` 許可。如需更多詳細資訊，請參閱 [存取控制](urls-auth.md)。

**Topics**
+ [函數 URL 呼叫基礎知識](#urls-invocation-basics)
+ [請求和回應承載](#urls-payloads)

## 函數 URL 呼叫基礎知識
<a name="urls-invocation-basics"></a>

如果您的函數 URL 使用 `AWS_IAM` 驗證類型，您必須使用 [AWS Signature 第 4 版 (SigV4)](https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html) 簽署各個 HTTP 請求。[Postman](https://quickstarts.postman.com/guide/aws/index.html?index=..%2F..index#2) 等工具提供使用 SigV4 簽署請求的內建功能。

如果您不使用工具簽署函數 URL 的 HTTP 請求，則必須使用 SigV4 手動簽署各個請求。您的函數 URL 收到請求時，Lambda 也會計算 SigV4 簽章。唯有簽章相符，Lambda 才會處理請求。如需使用 SigV4 手動簽署請求的相關說明，請參閱《Amazon Web Services 一般參考 指南》**中的[使用 Signature 第 4 版簽署 AWS 請求](https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html)。

如果您的函數 URL 使用 `NONE` 驗證類型，您不必使用 SigV4 簽署請求。您可以使用 Web 瀏覽器、curl、Postman 或任何 HTTP 用戶端來呼叫您的函數。

如要測試函數的簡易 `GET` 請求，請使用 Web 瀏覽器。例如，如果函數 URL 為 `https://abcdefg.lambda-url.us-east-1.on.aws`，而且接受字串參數 `message`，則請求 URL 可能如下所示：

```
https://abcdefg.lambda-url.us-east-1.on.aws/?message=HelloWorld
```

如要測試其他 HTTP 請求 (例如 `POST` 請求)，您可以使用 curl 等工具。例如，如果您希望在函數 URL 的 `POST` 請求中納入某些 JSON 資料，您可以使用下列 curl 命令：

```
curl -v 'https://abcdefg.lambda-url.us-east-1.on.aws/?message=HelloWorld' \
-H 'content-type: application/json' \
-d '{ "example": "test" }'
```

## 請求和回應承載
<a name="urls-payloads"></a>

用戶端呼叫您的函數 URL 時，Lambda 會先將請求映射至事件物件，再將請求傳遞給函數。接著，函數的回應會映射至 Lambda 透過函數 URL 回傳給用戶端的 HTTP 回應。

請求和回應事件格式會採取與 [Amazon API Gateway 承載格式 2.0 版](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html#http-api-develop-integrations-lambda.proxy-format)一樣的結構描述。

### 請求承載格式
<a name="urls-request-payload"></a>

請求承載的結構如下：

```
{
  "version": "2.0",
  "routeKey": "$default",
  "rawPath": "/my/path",
  "rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
  "cookies": [
    "cookie1",
    "cookie2"
  ],
  "headers": {
    "header1": "value1",
    "header2": "value1,value2"
  },
  "queryStringParameters": {
    "parameter1": "value1,value2",
    "parameter2": "value"
  },
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "<urlid>",
    "authentication": null,
    "authorizer": {
        "iam": {
                "accessKey": "AKIA...",
                "accountId": "111122223333",
                "callerId": "AIDA...",
                "cognitoIdentity": null,
                "principalOrgId": null,
                "userArn": "arn:aws:iam::111122223333:user/example-user",
                "userId": "AIDA..."
        }
    },
    "domainName": "<url-id>.lambda-url.us-west-2.on.aws",
    "domainPrefix": "<url-id>",
    "http": {
      "method": "POST",
      "path": "/my/path",
      "protocol": "HTTP/1.1",
      "sourceIp": "123.123.123.123",
      "userAgent": "agent"
    },
    "requestId": "id",
    "routeKey": "$default",
    "stage": "$default",
    "time": "12/Mar/2020:19:03:58 +0000",
    "timeEpoch": 1583348638390
  },
  "body": "Hello from client!",
  "pathParameters": null,
  "isBase64Encoded": false,
  "stageVariables": null
}
```


| 參數 | 描述 | 範例 | 
| --- | --- | --- | 
|  `version`  |  此事件的承載格式版本。Lambda 函數 URL 目前支援[承載格式 2.0 版](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html#http-api-develop-integrations-lambda.proxy-format)。  |  `2.0`  | 
|  `routeKey`  |  函數 URL 不使用此參數。Lambda 將此設為 `$default` 作為預留位置使用。  |  `$default`  | 
|  `rawPath`  |  請求路徑。例如，如果請求 URL 為 `https://{url-id}.lambda-url.{region}.on.aws/example/test/demo`，則原始路徑值為 `/example/test/demo`。  |  `/example/test/demo`  | 
|  `rawQueryString`  |  內含請求查詢字串參數的原始字串。支援的字元包含 `a-z`、`A-Z`、`0-9`、`.`、`_`、`-`、`%`、`&`、`=`，以及 `+`。  |  `"?parameter1=value1&parameter2=value2"`  | 
|  `cookies`  |  內含隨請求一併傳送之所有 Cookie 的陣列。  |  `["Cookie_1=Value_1", "Cookie_2=Value_2"]`  | 
|  `headers`  |  以鍵值對形式呈現的請求標頭清單。  |  `{"header1": "value1", "header2": "value2"}`  | 
|  `queryStringParameters`  |  請求的查詢參數。例如，如果請求 URL 為 `https://{url-id}.lambda-url.{region}.on.aws/example?name=Jane`，則 `queryStringParameters` 值為具備索引鍵 `name` 和值 `Jane` 的 JSON 物件。  |  `{"name": "Jane"}`  | 
|  `requestContext`  |  內含請求其他資訊的物件，例如 `requestId`、請求的時間，以及呼叫者的身分 (如果透過 AWS Identity and Access Management (IAM) 取得授權的話)。  |   | 
|  `requestContext.accountId`  |  函數擁有者的 AWS 帳戶 ID。  |  `"123456789012"`  | 
|  `requestContext.apiId`  |  函數 URL 的 ID。  |  `"33anwqw8fj"`  | 
|  `requestContext.authentication`  |  函數 URL 不使用此參數。Lambda 將此設為 `null`。  |  `null`  | 
|  `requestContext.authorizer`  |  內含呼叫者身分相關資訊的物件 (如果函數 URL 使用 `AWS_IAM` 驗證類型的話)，否則 Lambda 會將此設為 `null`。  |   | 
|  `requestContext.authorizer.iam.accessKey`  |  呼叫者身分的存取金鑰。  |  `"AKIAIOSFODNN7EXAMPLE"`  | 
|  `requestContext.authorizer.iam.accountId`  |  呼叫者身分的 AWS 帳戶 ID。  |  `"111122223333"`  | 
|  `requestContext.authorizer.iam.callerId`  |  呼叫者的 ID (使用者 ID)。  |  `"AIDACKCEVSQ6C2EXAMPLE"`  | 
|  `requestContext.authorizer.iam.cognitoIdentity`  |  函數 URL 不使用此參數。Lambda 將此設為 `null`，或將此從 JSON 排除。  |  `null`  | 
|  `requestContext.authorizer.iam.principalOrgId`  |  與呼叫者身分相關聯的委託人組織 ID。  |  `"AIDACKCEVSQORGEXAMPLE"`  | 
|  `requestContext.authorizer.iam.userArn`  |  呼叫者身分的使用者 Amazon Resource Name (ARN)。  |  `"arn:aws:iam::111122223333:user/example-user"`  | 
|  `requestContext.authorizer.iam.userId`  |  呼叫者身分的使用者 ID。  |  `"AIDACOSFODNN7EXAMPLE2"`  | 
|  `requestContext.domainName`  |  函數 URL 的網域名稱。  |  `"<url-id>.lambda-url.us-west-2.on.aws"`  | 
|  `requestContext.domainPrefix`  |  函數 URL 的網域前綴。  |  `"<url-id>"`  | 
|  `requestContext.http`  |  內含 HTTP 請求詳細資訊的物件。  |   | 
|  `requestContext.http.method`  |  此請求所採用的 HTTP 方法。有效值包括 `GET`、`POST`、`PUT`、`HEAD`、`OPTIONS`、`PATCH` 和 `DELETE`。  |  `GET`  | 
|  `requestContext.http.path`  |  請求路徑。例如，如果請求 URL 為 `https://{url-id}.lambda-url.{region}.on.aws/example/test/demo`，則路徑值為 `/example/test/demo`。  |  `/example/test/demo`  | 
|  `requestContext.http.protocol`  |  請求的通訊協定。  |  `HTTP/1.1`  | 
|  `requestContext.http.sourceIp`  |  提出請求之即時 TCP 連線的來源 IP 地址。  |  `123.123.123.123`  | 
|  `requestContext.http.userAgent`  |  使用者代理程式請求標頭的值。  |  `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Gecko/20100101 Firefox/42.0`  | 
|  `requestContext.requestId`  |  呼叫請求的 ID。您可以使用此 ID 追蹤與函數相關的呼叫日誌。  |  `e1506fd5-9e7b-434f-bd42-4f8fa224b599`  | 
|  `requestContext.routeKey`  |  函數 URL 不使用此參數。Lambda 將此設為 `$default` 作為預留位置使用。  |  `$default`  | 
|  `requestContext.stage`  |  函數 URL 不使用此參數。Lambda 將此設為 `$default` 作為預留位置使用。  |  `$default`  | 
|  `requestContext.time`  |  請求的時間戳記。  |  `"07/Sep/2021:22:50:22 +0000"`  | 
|  `requestContext.timeEpoch`  |  Unix epoch 時間格式的請求時間戳記。  |  `"1631055022677"`  | 
|  `body`  |  請求的本文。如果請求的內容屬於二進位類型，則本文會採用 base64 編碼。  |  `{"key1": "value1", "key2": "value2"}`  | 
|  `pathParameters`  |  函數 URL 不使用此參數。Lambda 將此設為 `null`，或將此從 JSON 排除。  |  `null`  | 
|  `isBase64Encoded`  |  如果本文為二進位承載並採用 base64 編碼，此值為 `TRUE`，否則為 `FALSE`。  |  `FALSE`  | 
|  `stageVariables`  |  函數 URL 不使用此參數。Lambda 將此設為 `null`，或將此從 JSON 排除。  |  `null`  | 

### 回應承載格式
<a name="urls-response-payload"></a>

函數傳回回應時，Lambda 會剖析回應內容，並將其轉換為 HTTP 回應。函數回應承載的格式如下：

```
{
   "statusCode": 201,
    "headers": {
        "Content-Type": "application/json",
        "My-Custom-Header": "Custom Value"
    },
    "body": "{ \"message\": \"Hello, world!\" }",
    "cookies": [
        "Cookie_1=Value1; Expires=21 Oct 2021 07:48 GMT",
        "Cookie_2=Value2; Max-Age=78000"
    ],
    "isBase64Encoded": false
}
```

Lambda 會為您推斷回應格式。如果您的函數傳回有效的 JSON，但未傳回 `statusCode`，則 Lambda 會採取下列假設：
+ `statusCode`is(`200` )
**注意**  
有效 `statusCode` 的範圍為 100 至 599。
+ `content-type`is(`application/json` )
+ `body` 是函數的回應。
+ `isBase64Encoded`is(`false` )

以下範例顯示 Lambda 函數輸出與回應承載之間的映射情形，以及回應承載與最終 HTTP 回應之間的映射情形。用戶端呼叫您的函數 URL 時，會看見 HTTP 回應。

**字串回應的輸出範例**


| Lambda 函數輸出 | 轉譯後的回應輸出 | HTTP 回應 (用戶端看見的內容) | 
| --- | --- | --- | 
|  <pre>"Hello, world!"</pre>  |  <pre>{<br />  "statusCode": 200,<br />  "body": "Hello, world!",<br />  "headers": {<br />    "content-type": "application/json"<br />  },<br />  "isBase64Encoded": false<br />}</pre>  |  <pre>HTTP/2 200<br />date: Wed, 08 Sep 2021 18:02:24 GMT<br />content-type: application/json<br />content-length: 15<br /><br />"Hello, world!"</pre>  | 

**JSON 回應的輸出範例**


| Lambda 函數輸出 | 轉譯後的回應輸出 | HTTP 回應 (用戶端看見的內容) | 
| --- | --- | --- | 
|  <pre>{<br />  "message": "Hello, world!"<br />}</pre>  |  <pre>{<br />  "statusCode": 200,<br />  "body": {<br />    "message": "Hello, world!"<br />  },<br />  "headers": {<br />    "content-type": "application/json"<br />  },<br />  "isBase64Encoded": false<br />}</pre>  |  <pre>HTTP/2 200<br />date: Wed, 08 Sep 2021 18:02:24 GMT<br />content-type: application/json<br />content-length: 34<br /><br />{<br />  "message": "Hello, world!"<br />}</pre>  | 

**自訂回應的輸出範例**


| Lambda 函數輸出 | 轉譯後的回應輸出 | HTTP 回應 (用戶端看見的內容) | 
| --- | --- | --- | 
|  <pre>{<br />   "statusCode": 201,<br />    "headers": {<br />        "Content-Type": "application/json",<br />        "My-Custom-Header": "Custom Value"<br />    },<br />    "body": JSON.stringify({<br />        "message": "Hello, world!"<br />    }),<br />    "isBase64Encoded": false<br />}</pre>  |  <pre>{<br />   "statusCode": 201,<br />    "headers": {<br />        "Content-Type": "application/json",<br />        "My-Custom-Header": "Custom Value"<br />    },<br />    "body": JSON.stringify({<br />        "message": "Hello, world!"<br />    }),<br />    "isBase64Encoded": false<br />}</pre>  |  <pre>HTTP/2 201<br />date: Wed, 08 Sep 2021 18:02:24 GMT<br />content-type: application/json<br />content-length: 27<br />my-custom-header: Custom Value<br /><br />{<br />  "message": "Hello, world!"<br />}</pre>  | 

### Cookie
<a name="urls-cookies"></a>

如要從函數傳回 Cookie，請勿手動新增 `set-cookie` 標頭。您應將 Cookie 加入回應承載物件中。Lambda 會自動轉譯 Cookie，並以 `set-cookie` 標頭形式新增至 HTTP 回應，如下所示。


| Lambda 函數輸出 | HTTP 回應 (用戶端看見的內容) | 
| --- | --- | 
|  <pre>{<br />   "statusCode": 201,<br />    "headers": {<br />        "Content-Type": "application/json",<br />        "My-Custom-Header": "Custom Value"<br />    },<br />    "body": JSON.stringify({<br />        "message": "Hello, world!"<br />    }),<br />    "cookies": [<br />        "Cookie_1=Value1; Expires=21 Oct 2021 07:48 GMT",<br />        "Cookie_2=Value2; Max-Age=78000"<br />    ],<br />    "isBase64Encoded": false<br />}</pre>  |  <pre>HTTP/2 201<br />date: Wed, 08 Sep 2021 18:02:24 GMT<br />content-type: application/json<br />content-length: 27<br />my-custom-header: Custom Value<br />set-cookie: Cookie_1=Value2; Expires=21 Oct 2021 07:48 GMT<br />set-cookie: Cookie_2=Value2; Max-Age=78000<br /><br />{<br />  "message": "Hello, world!"<br />}</pre>  | 