通过 HTTP 请求调用函数


您可以使用 functions.https 来通过 HTTP 请求触发函数。这样您就能通过受支持的 HTTP 方法(GETPOSTPUTDELETEOPTIONS)调用同步函数。

本页面中的示例均基于一个示例函数,该函数会在您向函数端点发送 HTTP GET 请求时触发。该示例函数会检索当前的服务器时间,按网址查询参数中的要求格式化该时间,并在 HTTP 响应中发送结果。

使用 HTTP 请求来触发函数

可以使用 functions.https 创建一个处理 HTTP 事件的函数。HTTP 函数的事件处理程序会监听 onRequest() 事件,该事件支持由 Express Web 框架管理的路由器和应用。

使用 Express 请求对象和响应对象

Request 对象和 Response 对象可用作 onRequest() 的参数,其中 Request 对象用于访问客户端发送的 HTTP 请求的属性,而 Response 对象用于将响应发回给客户端。

exports.date = functions.https.onRequest((req, res) => {
  // ...
});

使用现有的 Express 应用

通过将 App 用作 onRequest() 的参数,您可以将一个完整的 Express 应用传递给 HTTP 函数。样板代码可以转移到中间件,如下所示:

const express = require('express');
const cors = require('cors');

const app = express();

// Automatically allow cross-origin requests
app.use(cors({ origin: true }));

// Add middleware to authenticate requests
app.use(myMiddleware);

// build multiple CRUD interfaces:
app.get('/:id', (req, res) => res.send(Widgets.getById(req.params.id)));
app.post('/', (req, res) => res.send(Widgets.create()));
app.put('/:id', (req, res) => res.send(Widgets.update(req.params.id, req.body)));
app.delete('/:id', (req, res) => res.send(Widgets.delete(req.params.id)));
app.get('/', (req, res) => res.send(Widgets.list()));

// Expose Express API as a single Cloud Function:
exports.widgets = functions.https.onRequest(app);

调用 HTTP 函数

部署 HTTP 函数后,您可以通过函数专属的网址来对其进行调用。网址包含顺序如下的多个元素:

  • 您在其中部署函数的区域(或多个区域)。一些生产函数可能需要明确设置位置以最大限度缩短网络延迟。
  • 您的 Firebase 项目 ID
  • cloudfunctions.net
  • 函数的名称

例如,用于调用 date() 的网址如下所示:

https://us-central1-<project-id>.cloudfunctions.net/date

如果在部署函数时遇到权限错误,请确保已将适当的 IAM 角色分配给运行部署命令的用户。

对于 Express 应用路由,函数名称会作为前缀添加到您定义的应用中的网址路径。例如,在上述 Express 应用示例中调用 getter 的网址如下所示:

https://us-central1-<project-id>.cloudfunctions.net/widgets/<id>

如果您调用受防火墙或 IP 过滤器保护的 HTTP 函数,可以查询 Google 用于提供 HTTP 函数的 IP 地址。

将中间件模块与 Cloud Functions 搭配使用

如果您需要注入中间件依赖项以启用 Cookie 支持或 CORS 等,请在函数内调用这些依赖项。例如,如需启用 CORS 支持,请添加以下代码块:

// Enable CORS using the `cors` express middleware.
cors(req, res, () => {
  // ...
});

从请求中读取值

下表列出了一些常见情景:

内容类型 请求正文 行为
application/json '{"name":"John"}' request.body.name 等于“John”
application/octet-stream “my text” request.body 等于“6d792074657874”(请求的原始字节;请参阅 Node.js 缓冲区文档
text/plain “my text” request.body 等于“my text”
application/x-www-form-urlencoded “name=John” request.body.name 等于“John”

此解析由以下正文解析器完成:

假设以下请求调用了您的函数:

curl -X POST -H "Content-Type:application/json" -H "X-MyHeader: 123" YOUR_HTTP_TRIGGER_ENDPOINT?foo=baz -d '{"text":"something"}'

发送的数据将在下列属性/方法下具体化:

属性/方法
req.method “POST”
req.get('x-myheader') “123”
req.query.foo “baz”
req.body.text “something”
req.rawBody 请求的原始(未解析)字节

date() 函数示例中,函数会同时测试网址参数和正文,以获取 format 值来设置要使用的日期/时间格式:

let format = req.query.format;
format = req.body.format;

终止 HTTP 函数

务必使用 send()redirect()end() 结束 HTTP 函数。否则,您的函数可能会继续运行,然后被系统强行终止。另请参阅同步、异步和 Promise

使用 Node.js moment 模块检索服务器时间并设置其格式后,date() 函数会在 HTTP 响应中发送结果并结束:

const formattedDate = moment().format(`${format}`);
functions.logger.log('Sending Formatted date:', formattedDate);
res.status(200).send(formattedDate);

将 HTTP 函数关联到 Firebase Hosting

您可以将 HTTP 函数关联到 Firebase Hosting。您的 Firebase Hosting 网站上的请求可以被代理到特定的 HTTP 函数。这还可以让您将自己的自定义域名用于 HTTP 函数。详细了解如何Cloud Functions 关联到 Firebase Hosting