

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

# 呼叫 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>  | 