Azure Functions HTTP 觸發程序

HTTP 觸發程序可讓您透過 HTTP 要求叫用函式。 您可以使用 HTTP 觸發程序來建置無伺服器 API 並回應 Webhook。

HTTP 觸發函式的預設傳回值為:

  • HTTP 204 No Content 具有 Functions 2.x 和更新版本中的空白主體
  • HTTP 200 OK 具有 Functions 1.x 中的空白主體

若要修改 HTTP 回應,請設定輸出繫結

如需有關 HTTP 繫結的詳細資訊,請參閱概觀輸出繫結參考

秘訣

如果您打算使用 HTTP 或 WebHook 的繫結,請做好規劃,以免因為 HttpClient 具現化不當而耗盡連接埠。 如需詳細資訊,請參閱如何管理 Azure Functions 中的連線

例如

您可以使用下列其中一種 C# 模式來建立 C# 函式:

  • 內含式類別庫:在與 Functions 執行階段相同的程序中執行的已編譯 C# 函式。
  • 隔離式程序類別庫:在與執行階段隔離的程序中執行的已編譯 C# 函式。 需要隔離的程序,才能支援在 .NET 5.0 上執行的 C# 函式。
  • C# 指令碼:主要用於在 Azure 入口網站中建立 C# 函式時使用。

此文章中的程式碼預設為 .NET Core 語法,用於 Functions 2.x 版和更新版本。 如需 1.x 語法的資訊,請參閱 1.x 函式範本

下列範例會顯示在查詢字串或 HTTP 要求主體中尋找 name 參數的 C# 函式。 請注意,傳回值用於輸出繫結,但傳回值屬性並非必要。

[FunctionName("HttpTriggerCSharp")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
    HttpRequest req, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string name = req.Query["name"];

    string requestBody = String.Empty;
    using (StreamReader streamReader =  new  StreamReader(req.Body))
    {
        requestBody = await streamReader.ReadToEndAsync();
    }
    dynamic data = JsonConvert.DeserializeObject(requestBody);
    name = name ?? data?.name;

    return name != null
        ? (ActionResult)new OkObjectResult($"Hello, {name}")
        : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}

本區段包含下列範例:

下列範例示範 HTTP 觸發程序繫結。

讀取查詢字串的參數

此範例會從查詢字串中讀取名為 id 的參數,並使用它來建立傳回至用戶端且內容類型為 application/json 的 JSON 文件。

@FunctionName("TriggerStringGet")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.GET}, 
            authLevel = AuthorizationLevel.ANONYMOUS)
        HttpRequestMessage<Optional<String>> request,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("GET parameters are: " + request.getQueryParameters());

    // Get named parameter
    String id = request.getQueryParameters().getOrDefault("id", "");

    // Convert and display
    if (id.isEmpty()) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final String name = "fake_name";
        final String jsonDocument = "{\"id\":\"" + id + "\", " + 
                                        "\"description\": \"" + name + "\"}";
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(jsonDocument)
                        .build();
    }
}

從 POST 要求讀取主體

此範例會讀取 POST 要求的主體,作為 String,並使用它來建立傳回至用戶端且內容類型為 application/json 的 JSON 文件。

    @FunctionName("TriggerStringPost")
    public HttpResponseMessage run(
            @HttpTrigger(name = "req", 
              methods = {HttpMethod.POST}, 
              authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {

        // Item list
        context.getLogger().info("Request body is: " + request.getBody().orElse(""));

        // Check request body
        if (!request.getBody().isPresent()) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                          .body("Document not found.")
                          .build();
        } 
        else {
            // return JSON from to the client
            // Generate document
            final String body = request.getBody().get();
            final String jsonDocument = "{\"id\":\"123456\", " + 
                                         "\"description\": \"" + body + "\"}";
            return request.createResponseBuilder(HttpStatus.OK)
                          .header("Content-Type", "application/json")
                          .body(jsonDocument)
                          .build();
        }
    }

從路由讀取參數

此範例會從路由路徑讀取名為 id 的必要參數,和選用參數 name,然後使用這些參數來建立傳回至用戶端且內容類型為 application/json 的 JSON 文件。 T

@FunctionName("TriggerStringRoute")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.GET}, 
            authLevel = AuthorizationLevel.ANONYMOUS,
            route = "trigger/{id}/{name=EMPTY}") // name is optional and defaults to EMPTY
        HttpRequestMessage<Optional<String>> request,
        @BindingName("id") String id,
        @BindingName("name") String name,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("Route parameters are: " + id);

    // Convert and display
    if (id == null) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final String jsonDocument = "{\"id\":\"" + id + "\", " + 
                                        "\"description\": \"" + name + "\"}";
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(jsonDocument)
                        .build();
    }
}

從 POST 要求讀取 POJO 主體

以下是此範例中所參照 ToDoItem 類別的程式碼:


public class ToDoItem {

  private String id;
  private String description;  

  public ToDoItem(String id, String description) {
    this.id = id;
    this.description = description;
  }

  public String getId() {
    return id;
  }

  public String getDescription() {
    return description;
  }

  @Override
  public String toString() {
    return "ToDoItem={id=" + id + ",description=" + description + "}";
  }
}

此範例會讀取 POST 要求的主體。 要求主體會自動還原序列化至 ToDoItem 物件,並傳回至用戶端,且內容類型為 application/jsonToDoItem 參數會在指派給 HttpMessageResponse.Builder 類別的 body 屬性時,由 Functions 執行階段序列化。

@FunctionName("TriggerPojoPost")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.POST}, 
            authLevel = AuthorizationLevel.ANONYMOUS)
        HttpRequestMessage<Optional<ToDoItem>> request,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("Request body is: " + request.getBody().orElse(null));

    // Check request body
    if (!request.getBody().isPresent()) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final ToDoItem body = request.getBody().get();
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(body)
                        .build();
    }
}

下列範例示範的是使用繫結之 function.json 檔案,以及 JavaScript 函式中的觸發程序繫結。 函式會尋找 name 參數,其位於查詢字串或 HTTP 要求的主體。

以下是 function.json 檔案:

{
    "disabled": false,    
    "bindings": [
        {
            "authLevel": "function",
            "type": "httpTrigger",
            "direction": "in",
            "name": "req"
        },
        {
            "type": "http",
            "direction": "out",
            "name": "res"
        }
    ]
}

設定章節會說明這些屬性。

以下是 JavaScript 程式碼:

module.exports = async function(context, req) {
    context.log('Node.js HTTP trigger function processed a request. RequestUri=%s', req.originalUrl);

    if (req.query.name || (req.body && req.body.name)) {
        context.res = {
            // status defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

下列範例示範 function.json 檔案中的觸發程序繫結,以及 PowerShell 函數。 函式會尋找 name 參數,其位於查詢字串或 HTTP 要求的主體。

{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    }
  ]
}
using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

$body = "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."

if ($name) {
    $body = "Hello, $name. This HTTP triggered function executed successfully."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body       = $body
})

下列範例示範 function.json 檔案中的觸發程序繫結,以及使用此繫結的 Python 函式。 函式會尋找 name 參數,其位於查詢字串或 HTTP 要求的主體。

以下是 function.json 檔案:

{
    "scriptFile": "__init__.py",
    "disabled": false,    
    "bindings": [
        {
            "authLevel": "function",
            "type": "httpTrigger",
            "direction": "in",
            "name": "req"
        },
        {
            "type": "http",
            "direction": "out",
            "name": "$return"
        }
    ]
}

設定章節會說明這些屬性。

以下是 Python 程式碼:

import logging
import azure.functions as func


def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        return func.HttpResponse(f"Hello {name}!")
    else:
        return func.HttpResponse(
            "Please pass a name on the query string or in the request body",
            status_code=400
        )

屬性

內含式隔離程序 C# 程式庫都會使用 HttpTriggerAttribute 來定義觸發程序繫結。 C# 指令碼會改用 function.json 設定檔。

內含式函數中,HttpTriggerAttribute 支援下列參數:

參數 描述
AuthLevel 會判斷要求中必須存在哪些金鑰 (若有的話) 才能叫用函式。 如需支援的值,請參閱授權層級
方法 函數將回應的 HTTP 方法陣列。 如果未指定,函式將會回應所有的 HTTP 方法。 請參閱自訂 HTTP 端點
路由 會定義路由範本,從而控制函式所要回應的要求 URL。 如果沒有提供任何值,預設值為 <functionname>。 如需詳細資訊,請參閱自訂 HTTP 端點
WebHookType 只有針對 1.x 版執行階段才有支援。

會設定 HTTP 觸發程序作為指定提供者的 webhook 接收器。 如需支援的值,請參閱 WebHook 類型

註解

Java 函數執行階段程式庫中,使用支援下列設定的 HttpTrigger 註釋:

組態

下表說明您在 function.json 檔案中設定的觸發程序設定屬性,且根據執行階段版本而有所不同。

下表說明您在 function.json 檔案中設定的繫結設定屬性。

function.json 屬性 描述
type 必要項目 - 必須設定為 httpTrigger
direction 必要項目 - 必須設定為 in
name 必要項目 - 函式程式碼中用於要求或要求主體的變數名稱。
authLevel 會判斷要求中必須存在哪些金鑰 (若有的話) 才能叫用函式。 如需支援的值,請參閱授權層級
methods 函數將回應的 HTTP 方法陣列。 如果未指定,函式將會回應所有的 HTTP 方法。 請參閱自訂 HTTP 端點
route 會定義路由範本,從而控制函式所要回應的要求 URL。 如果沒有提供任何值,預設值為 <functionname>。 如需詳細資訊,請參閱自訂 HTTP 端點

使用方式

本節詳細說明如何設定 HTTP 觸發程序函數繫結。

HttpTrigger 註釋應該套用至下列其中一種類型的方法參數:

  • HttpRequestMessage<T>
  • 任何原生 JAVA 類型,例如 int、String、byte[]。
  • 使用選擇性的可為 Null 值。
  • 任何簡單的 Java 物件 (POJO) 類型。

Payload

觸發程序輸入類型會宣告為 HttpRequest 或自訂類型。 如果您選擇 HttpRequest,就會取得要求物件的完整存取權。 針對自訂的類型,執行階段會嘗試剖析 JSON 要求本文來設定物件屬性。

自訂 HTTP 端點

根據預設,當您為 HTTP 觸發程序建立函式時,將可透過下列形式的路由來定址該函式:

http://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>

您可以在 HTTP 觸發程序的輸入繫結上使用選擇性的 route 屬性來自訂此路由。 您可以將任何 Web API 路由條件約束與您的參數搭配使用。

下列 C# 函式程式碼在路由中接受兩個參數 categoryid,並使用這兩個參數來寫入回應。

[FunctionName("Function1")]
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "products/{category:alpha}/{id:int?}")] HttpRequest req,
string category, int? id, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    var message = String.Format($"Category: {category}, ID: {id}");
    return (ActionResult)new OkObjectResult(message);
}

路由參數是使用 HttpTrigger 註釋的 route 設定來定義。 下列函數程式碼會在路由中接受兩個參數 categoryid,並使用這兩個參數來寫入回應。

package com.function;

import java.util.*;
import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.*;

public class HttpTriggerJava {
    public HttpResponseMessage<String> HttpTrigger(
            @HttpTrigger(name = "req",
                         methods = {"get"},
                         authLevel = AuthorizationLevel.FUNCTION,
                         route = "products/{category:alpha}/{id:int}") HttpRequestMessage<String> request,
            @BindingName("category") String category,
            @BindingName("id") int id,
            final ExecutionContext context) {

        String message = String.format("Category  %s, ID: %d", category, id);
        return request.createResponseBuilder(HttpStatus.OK).body(message).build();
    }
}

舉例來說,下列 function.json 檔案使用兩個參數 categoryid 定義了 HTTP 觸發程序的 route 屬性:

{
    "bindings": [
    {
        "type": "httpTrigger",
        "name": "req",
        "direction": "in",
        "methods": [ "get" ],
        "route": "products/{category:alpha}/{id:int?}"
    },
    {
        "type": "http",
        "name": "res",
        "direction": "out"
    }
    ]
}

函數執行階段會提供來自 context 物件的要求本文。 下列範例示範如何從 context.bindingData 讀取路由參數。

module.exports = async function (context, req) {

    var category = context.bindingData.category;
    var id = context.bindingData.id;
    var message = `Category: ${category}, ID: ${id}`;

    context.res = {
        body: message;
    }
}

可以 $Request.Params 物件的屬性形式存取在 function.json 檔案中宣告的路由參數。

$Category = $Request.Params.category
$Id = $Request.Params.id

$Message = "Category:" + $Category + ", ID: " + $Id

Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $Message
})

函式執行內容是透過宣告為 func.HttpRequest 的參數公開。 這個執行個體可讓函式存取資料路由參數、查詢字串值和方法,讓您能夠傳回 HTTP 回應。

一旦定義,即可透過呼叫 route_params 方法,將路由參數提供給函式。

import logging

import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:

    category = req.route_params.get('category')
    id = req.route_params.get('id')
    message = f"Category: {category}, ID: {id}"

    return func.HttpResponse(message)

在使用此設定的情況下,現在便可使用下列路由來定址該函式,而不需使用原始路由。

http://<APP_NAME>.azurewebsites.net/api/products/electronics/357

此設定可讓函數程式碼支援位址、類別識別碼中的兩個參數。如需如何在 URL 中標記路由參數的詳細資訊,請參閱在 ASP.NET Core 中路由

所有函式路由預設前面都會加上 api。 您也可以在 host.json 檔案中使用 extensions.http.routePrefix 屬性來自訂或移除前置詞。 下列範例會在 host.json 檔案中使用空字串作為前置詞來移除 api 路由前置詞。

{
    "extensions": {
        "http": {
            "routePrefix": ""
        }
    }
}

使用路由參數

定義函式 route 模式的路由參數可用於每個繫結。 例如,如果您有定義為 "route": "products/{id}" 的路由,則資料表儲存體繫結可以使用繫結設定中 {id} 參數的值。

下列設定顯示如何將 {id} 參數傳遞至繫結的 rowKey

{
    "type": "table",
    "direction": "in",
    "name": "product",
    "partitionKey": "products",
    "tableName": "products",
    "rowKey": "{id}"
}

當您使用路由參數時,系統會自動為函數建立 invoke_URL_template。 用戶端可以使用 URL 範本來瞭解使用 URL 呼叫函數時傳入 URL 所需的參數。 瀏覽至 Azure 入口網站中的其中一個 HTTP 觸發函數,然後選取 [取得函數 URL]。

您可以使用列出函數取得函數的 Azure Resource Manager API,以程式設計方式存取 invoke_URL_template

使用用戶端身分識別

如果您的函式應用程式使用 App Service 驗證/授權,您可以透過程式碼來檢視已驗證的用戶端相關資訊。 這項資訊是以由平台插入的要求標頭形式提供。

您也可以從繫結資料來讀取這項資訊。 這項功能僅適用於 Functions 2.x 和更新版本的執行階段。 它目前也僅適用於 .NET 語言。

有關已驗證用戶端的資訊會以 ClaimsPrincipal 的形式提供,可做為要求內容的一部分使用,如下列範例所示:

using System.Net;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

public static IActionResult Run(HttpRequest req, ILogger log)
{
    ClaimsPrincipal identities = req.HttpContext.User;
    // ...
    return new OkObjectResult();
}

ClaimsPrincipal 也可以直接納入為函式簽章中的額外參數:

using System.Net;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using Newtonsoft.Json.Linq;

public static void Run(JObject input, ClaimsPrincipal principal, ILogger log)
{
    // ...
    return;
}

通過驗證的使用者可透過 HTTP 標頭取得。

授權層級

授權層級是字串值,表示存取函數端點所需的授權金鑰種類。 針對 HTTP 觸發的函數,授權層級可以是下列其中一個值:

層級值 描述
匿名 不需要 API 金鑰。
函數 需要函式專屬的 API 金鑰。 當層級未特別設定時,這是預設值。
admin 需要主要金鑰。

函式存取金鑰

Functions 可讓您使用金鑰來提高開發期間存取 HTTP 函式端點的困難度。 除非 HTTP 觸發程序函數的 HTTP 存取層級設定為 anonymous,否則要求必須在要求中包含 API 存取金鑰。

雖然金鑰提供預設安全性機制,但您可能想要考慮其他選項來保護生產環境中的 HTTP 端點。 例如,在公用應用程式中散發共用秘密通常不是很好的做法。 如果您的函式是從公用用戶端呼叫,您可能想要考慮實作另一個安全性機制。 若要深入了解,請參閱在生產環境中保護 HTTP 端點

當更新函式索引鍵值時,您必須手動將更新的索引鍵值重新散發給所有呼叫您函式的用戶端。

授權範圍 (函式層級)

函式層級金鑰有兩個存取範圍:

  • Function:這些金鑰僅適用於據以定義它們的特定函式。 當做為 API 金鑰使用時,這些金鑰僅允許存取該函式。

  • 主機:具有主機範圍的金鑰可用來存取函數應用程式內的所有函式。 當做為 API 金鑰使用時,這些金鑰會允許存取函數應用程式中的任何函式。

每個金鑰均為具名以供參考,並且在函式和主機層級有一預設金鑰 (名稱為 "default")。 函式金鑰的優先順序高於主機金鑰。 當您使用相同的名稱來定義兩個金鑰時,一律會使用函式金鑰。

主要金鑰 (管理員層級)

每個函數應用程式也有一個名為 _master 的管理員層級主機金鑰。 除了為應用程式中的所有函式提供主機層級存取之外,主要金鑰也會提供執行階段 REST API 的系統管理存取權。 無法撤銷此金鑰。 當您將存取層級設定為 admin 時,要求就必須使用主要金鑰;任何其他金鑰則會導致存取失敗。

注意

由於主要金鑰會在您的函數應用程式中授與提高的權限,因此您不應該與第三方共用此金鑰,或是在原生用戶端應用程式中散發它。 當您選擇管理存取層級時,請務必謹慎。

取得金鑰

金鑰會當作您函數應用程式的一部分儲存於 Azure 中,並在加密後靜置。 若要檢視金鑰,請建立新的金鑰或將金鑰輪替為新的值,瀏覽至您在 Azure 入口網站中的其中一個 HTTP 觸發函數,然後選取 [函數金鑰]。

您也可以管理主機金鑰。 瀏覽至 Azure 入口網站中的函數應用程式,然後選取 [應用程式金鑰]。

您可以使用 Azure Resource Manager API,以程式設計方式取得函數和主機金鑰。 有 API 可用來列出函數金鑰列出主機金鑰,而使用部署插槽時,對等 API 是列出函數金鑰插槽列出主機金鑰插槽

您也可以使用建立或更新函數祕密建立或更新函數祕密插槽建立或更新主機祕密建立或更新主機祕密插槽 API,以程式設計方式建立新的函數和主機金鑰。

您可以使用刪除函數祕密刪除函數祕密插槽刪除主機祕密刪除主機祕密插槽 API,以程式設計方式刪除函數和主機金鑰。

您也可以使用舊版金鑰管理 API 來取得函數金鑰,但建議改用 Azure Resource Manager API。

API 金鑰授權

大多數 HTTP 觸發程序範本都會要求在要求中有 API 金鑰。 因此,您的 HTTP 要求通常看起來會像以下 URL:

https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?code=<API_KEY>

金鑰可包含在名為 code 的查詢字串變數中,如以上所示。 它也可以包含在 x-functions-key HTTP 標頭中。 金鑰的值可以是針對函式定義的任何函式金鑰,或是任何主機金鑰。

您可以允許匿名要求,這不需要金鑰。 您也可以要求使用主要金鑰。 您可以使用繫結 JSON 中的 authLevel 屬性來變更預設授權層級。 如需詳細資訊,請參閱觸發程序 - 組態

注意

在本機執行函式時,不論指定的驗證等級設定為何,都會停用授權。 發佈至 Azure 之後,就會強制執行您觸發程序中的 authLevel 設定。 在容器中本機執行時,仍然需要金鑰。

在生產環境中保護 HTTP 端點

若要在生產環境中完全保護您的函式端點,您應該考慮實作下列其中一個函數應用程式等級安全性選項。 當使用這其中一種函數應用程式等級的安全性方法時,您應該將 HTTP 觸發的函式驗證等級設定為 anonymous

啟用 App Service 驗證/授權

App Service 平台可讓您使用 Azure Active Directory (AAD) 及數個協力廠商身分識別提供者來驗證用戶端。 您可以使用此策略為函式實作自訂授權規則,並可使用來自函式程式碼的使用者資訊。 若要深入了解,請參閱 Azure App Service 中的驗證與授權使用用戶端身分識別

使用「Azure API 管理」(APIM) 來驗證要求

APIM 為傳入要求提供多種 API 安全性選項。 若要深入了解,請參閱 API 管理驗證原則。 備妥 APIM 之後,您可以設定讓函數應用程式只接受來自您 APIM 執行個體 IP 位址的要求。 若要深入了解,請參閱 IP 位址限制

以隔離方式部署函式應用程式

Azure App Service 環境 (ASE) 提供一個可供執行您函式的專用主控環境。 ASE 可讓您設定一個單一前端閘道,可用來驗證所有傳入要求。 如需詳細資訊,請參閱設定 App Service Environment 的 Web 應用程式防火牆 (WAF)

Webhook

注意

Webhook 模式僅適用於 1.x 版 Functions 執行階段。 此變更已完成,可在版本 2.x 和更新版本中提升 HTTP 觸發程序的效能。

在版本 1.x 中,Webhook 範本會提供 Webhook 承載的額外驗證。 在 2.x 和更新版本中,基底 HTTP 觸發程序仍然可運作,並且對 Webhook 來說是建議採用的方法。

WebHook 類型

webHookType 繫結屬性會指出函數支援的 Webhook 類型,這也會指示支援的承載。 Webhook 類型可以是下列值其中之一:

類型值 描述
genericJson 一般用途的 Webhook 端點,不需要特定提供者的邏輯。 此設定會將要求限制為只有那些使用 HTTP POST 和包含 application/json 內容類型的要求。
github 函式會回應 GitHub Webhook。 請勿搭配 GitHub Webhook 使用 authLevel 屬性。
slack 函式會回應 Slack Webhook。 請勿搭配 Slack Webhook 使用 authLevel 屬性。

設定 webHookType 屬性時,請勿在繫結上設定 methods 屬性。

GitHub Webhook

若要回應 GitHub Webhook,請先建立含有 HTTP 觸發程序的函式,然後將 webHookType 屬性設定為 github。 接著將其 URL 和 API 金鑰複製到您 GitHub 存放庫的 [新增 Webhook] 頁面。

顯示如何為函數新增 webhook 的螢幕擷取畫面。

Slack Webhook

Slack webhook 會為您產生權杖,而不是由您指定,因此您必須使用 Slack 的權杖來設定函式專屬的金鑰。 請參閱授權金鑰

Webhook 和金鑰

Webhook 授權是由 Webhook 接收器元件 (HTTP 觸發程序的一部分) 處理,處理機制則會以 Webhook 類型作為基礎而有所不同。 每個機制都依賴金鑰。 根據預設,將會使用名稱為 "default" 的函式金鑰。 如需使用不同的金鑰,請設定 Webhook 提供者以下列其中一種方式將金鑰名稱隨著要求一起傳送:

  • 查詢字串:提供者會在 clientid 查詢字串參數中傳遞金鑰名稱,例如 https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?clientid=<KEY_NAME>
  • 要求標頭:提供者會在 x-functions-clientid 標頭中傳遞金鑰名稱。

內容類型

將二進位和表單資料傳遞至非 C# 函式需要您使用適當的內容類型標頭。 支援的內容類型包括二進位資料的 octet-stream多部分類型

已知問題

在非 C# 函式中,以內容類型 image/jpeg 傳送的要求會產生傳遞至函式的 string 值。 在這些情況下,您可以手動將 string 值轉換為位元組陣列,以存取原始二進位資料。

限制

HTTP 要求長度的限制為 100 MB (104,857,600 個位元組),而 URL 長度的限制為 4 KB (4,096 個位元組)。 這些限制由執行階段 Web.config 檔案httpRuntime 元素所指定。

如果使用 HTTP 觸發程序的函式未在約 230 秒內完成,Azure Load Balancer 將會逾時並傳回 HTTP 502 錯誤。 函式會繼續執行,但無法傳回 HTTP 回應。 對於長時間執行的函式,建議您遵循非同步模式,並傳回可以偵測要求狀態的位置。 如需函式可以執行多久的相關資訊,請參閱級別和裝載 - 使用情況方案

後續步驟