在 Cloud Run 中,如果您要通过 HTTP(S) 请求调用函数,请编写 HTTP 函数。为了支持 HTTP 语义,您可以使用函数框架,并指定 HTTP 函数签名以接受 HTTP 特有的参数。
实现 HTTP 处理程序函数
以下示例展示了每个运行时的基本 HTTP 函数源文件。如需了解源代码的位置,请参阅源目录结构。
Node.js
const functions = require('@google-cloud/functions-framework');
// Register an HTTP function with the Functions Framework
functions.http('myHttpFunction', (req, res) => {
// Your code here
// Send an HTTP response
res.send('OK');
});
在 Node.js 中,您可以向 Node.js 版 Functions 框架注册 HTTP 处理程序函数。HTTP 处理程序函数必须是 Express 中间件函数,该函数会接受请求和响应参数并发送 HTTP 响应。
Cloud Run 使用 body-parser
根据请求的 Content-Type
标头为您自动解析请求正文,因此您可以在 HTTP 处理程序中访问 req.body
和 req.rawBody
对象。
函数入口点是向 Functions 框架注册处理程序时使用的名称。在此示例中,入口点为 myHttpFunction
。
Python
import functions_framework
# Register an HTTP function with the Functions Framework
@functions_framework.http
def my_http_function(request):
# Your code here
# Return an HTTP response
return 'OK'
在 Python 中,您可以向 Python 版 Functions 框架注册 HTTP 处理程序函数。HTTP 处理程序函数必须接受 Flask 请求对象作为参数,并返回 Flask 可以将其转换为 HTTP 响应对象的值。
函数入口点是向 Functions 框架注册处理程序时使用的名称。在此示例中,入口点为 my_http_function
。
Go
package myhttpfunction
import (
"fmt"
"net/http"
"github.com/GoogleCloudPlatform/functions-framework-go/functions"
)
func init() {
// Register an HTTP function with the Functions Framework
functions.HTTP("MyHTTPFunction", myHTTPFunction)
}
// Function myHTTPFunction is an HTTP handler
func myHTTPFunction(w http.ResponseWriter, r *http.Request) {
// Your code here
// Send an HTTP response
fmt.Fprintln(w, "OK")
}
在 Go 中,您可以在 init()
函数中向 Go 版 Functions 框架注册 HTTP 处理程序函数。HTTP 处理程序函数必须使用标准 http.HandlerFunc
接口发送 HTTP 响应。
函数入口点是向 Functions 框架注册处理程序时使用的名称。在此示例中,入口点为 MyHTTPFunction
。
HTTP 处理程序函数必须实现标准 http.HandlerFunc
接口。它接受您的函数用于创建请求的 http.ResponseWriter 接口,以及指向包含入站 HTTP 请求详细信息的 http.Request 结构体的指针。
Java
package myhttpfunction;
import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
// Define a class that implements the HttpFunction interface
public class MyHttpFunction implements HttpFunction {
// Implement the service() method to handle HTTP requests
@Override
public void service(HttpRequest request, HttpResponse response) throws Exception {
// Your code here
// Send an HTTP response
response.getWriter().write("OK");
}
}
在 Java 中,您需要使用 Functions Framework Java API 通过 HttpFunction
接口实现 HTTP 处理程序类。service()
方法必须发送 HTTP 响应。
函数入口点是 HTTP 处理程序类的完全限定名称,包括软件包名称。在此示例中,入口点为 myhttpfunction.MyHttpFunction
。
您的 service
方法会收到描述入站 HTTP 请求的 HttpRequest
对象以及函数填充来响应消息的 HttpResponse
对象。
.NET
using Google.Cloud.Functions.Framework;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
namespace MyProject
{
// Define a class that implements the IHttpFunction interface
public class MyHttpFunction : IHttpFunction
{
// Implement the HandleAsync() method to handle HTTP requests
public async Task HandleAsync(HttpContext context)
{
// Your code here
// Send an HTTP response
await context.Response.WriteAsync("OK");
}
}
}
在 .NET 运行时中,您可以使用 .NET 版 Functions 框架 通过 IHttpFunction
接口实现 HTTP 处理程序类。HandleAsync()
方法接受标准 ASP.NET HttpContext
对象作为参数,并且必须发送 HTTP 响应。
函数入口点是 HTTP 处理程序类的完全限定名称,包括命名空间。在此示例中,入口点为 MyProject.MyHttpFunction
。
Ruby
require "functions_framework"
# Register an HTTP function with the Functions Framework
FunctionsFramework.http "my_http_function" do |request|
# Your code here
# Return an HTTP response
"OK"
end
在 Ruby 中,您可以向 Ruby 版 Functions 框架注册 HTTP 处理程序函数。HTTP 处理程序函数必须接受 Rack 请求对象作为参数,并返回可用作 HTTP 响应的值。
函数入口点是向 Functions 框架注册处理程序时使用的名称。在此示例中,入口点为 my_http_function
。
PHP
<?php
use Google\CloudFunctions\FunctionsFramework;
use Psr\Http\Message\ServerRequestInterface;
// Register an HTTP function with the Functions Framework
FunctionsFramework::http('myHttpFunction', 'myHttpHandler');
// Define your HTTP handler
function myHttpHandler(ServerRequestInterface $request): string
{
// Your code here
// Return an HTTP response
return 'OK';
}
在 PHP 中,您可以向 PHP 版 Functions 框架注册 HTTP 处理程序函数。HTTP 处理程序函数必须接受实现 PSR-7 ServerRequestInterface
接口的参数,并且必须以字符串或对象形式返回 HTTP 响应以实现 PSR-7 ResponseInterface
接口。
函数入口点是向 Functions 框架注册处理程序时使用的名称。在此示例中,入口点为 myHttpFunction
。
HTTP 请求和响应
向 Functions 框架注册 HTTP 处理程序函数后,您的 HTTP 处理程序可以检查请求方法,并根据该方法执行不同的操作。
当您将事件提供程序配置为向 Cloud Run 函数发送 HTTP 请求时,该函数会发送 HTTP 响应。如果函数创建了后台任务(例如使用线程、future、JavaScript Promise 对象、回调或系统进程),则必须先终止这些任务或以其他方式对其进行解析,然后再发送 HTTP 响应。在 HTTP 响应发送之前未终止的任何任务都可能无法完成,并且可能导致未定义的行为。
处理 CORs / CORS 支持
跨域资源共享 (CORS) 的作用是让一个网域上运行的应用访问另一网域中的资源。例如,您可能需要让您的网域向 Cloud Functions 网域发出请求以访问函数。
如需允许向您的函数发出非同源请求,请在 HTTP 响应中根据需要设置 Access-Control-Allow-Origin
标头。对于预检非同源请求,您必须使用 204
响应代码和其他标头来响应预检 OPTIONS
请求。
Node.js
Python
Go
Java
.NET
Ruby
PHP
如果 CORS 未正确设置,则可能会出现如下错误:
XMLHttpRequest cannot load https://YOUR_FUNCTION_URL. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://YOUR_DOMAIN' is therefore not allowed access.
CORS 限制
对于预检非同源请求,系统会在没有 Authorization 标头的情况下发送预检 OPTIONS 请求,因此所有需要身份验证的 HTTP 函数都会拒绝这些请求。由于预检请求失败,因此主请求也将失败。如需规避此限制,请使用以下选项之一:
- 允许对函数进行未经身份验证的调用。
- 在同一网域上托管您的 Web 应用和 Cloud Run,以避免 CORS。您可以通过将 Firebase Hosting 与 Cloud Run 函数相集成来实现此目的。