我有一个 Nodejs API,它在响应中返回一个 PDF 文件。它将 PDF 作为二进制数据返回。在我的前端,我使用一个名为 React-PDF 的包,它获取 PDF 端点 url 并获取要显示的数据。在我决定切换到无服务器框架(包括无服务器离线)之前,这一切都运行得很好。
现在切换到无服务器后,当我的前端获取 PDF 时,它无法加载并向控制台记录警告
Warning: Indexing all PDF objects
。我使用 vbindiff 工具比较了从普通 Nodejs Express API 下载的相同 PDF 文件与使用无服务器框架从 API 下载的文件,我发现这两个文件的长度相同,但从无服务器 API 下载的文件长度不同有些地方内容不同。
我发现了一些类似的问题,讨论无服务器和二进制数据的问题,我将它们推荐的配置添加到应该允许二进制数据的 serverless.yml 文件中,但这对结果没有任何改变。
这里是建议添加的配置,以允许二进制数据通过API网关
provider:
apiGateway:
binaryMediaTypes:
- "*/*"
这是我完整的 serverless.yml 文件
service: flightchecklists-backend
frameworkVersion: "3"
provider:
name: aws
runtime: nodejs12.x
memorySize: 1024
timeout: 30
region: ${opt:region}
# To allow binary pdf responses.
apiGateway:
binaryMediaTypes:
- "*/*"
functions:
handler:
handler: server.handler
events:
- http:
path: /
method: ANY
cors: true
- http:
path: /{proxy+}
method: ANY
cors: true
plugins:
- serverless-offline
custom:
serverless-offline:
noPrependStageInUrl: true
httpPort: 3000
这是我的 server.js 文件
"use strict";
require("dotenv").config();
require("log-aws-lambda")();
const express = require("express");
const serverless = require("serverless-http");
const bodyParser = require("body-parser");
const path = require("path");
const cors = require("cors");
const app = express();
const checklists = require("./routes/checklists");
const checkout = require("./routes/checkout");
const customerPortal = require("./routes/customerPortal");
const paymentUsers = require("./routes/paymentUsers");
const webhook = require("./routes/webhook");
const subscriptions = require("./routes/subscriptions");
const orders = require("./routes/orders");
const isAdmin = require("./routes/isAdmin");
const blockExternalRequests = require("./middleware/blockExternalRequests");
const namedLogger = require("./utils/logger");
const logger = new namedLogger("server.js");
const port = 3000;
// Cors
app.use(cors());
// Webhook route (Needs to be before bodyparser)
app.use("/webhook", webhook);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// View engine
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "pug");
app.use(
"/static",
blockExternalRequests,
express.static(path.join(__dirname, "public"))
);
// Routes
app.use("/checklists", checklists);
app.use("/create-checkout-session", checkout);
app.use("/create-portal-session", customerPortal);
app.use("/paymentusers", paymentUsers);
app.use("/subscriptions", subscriptions);
app.use("/orders", orders);
app.use("/isadmin", isAdmin);
// Comment when using serverless.
app.listen(port, () => {
logger.info(`Server started on port ${port}...`);
});
// Export for tests
// module.exports = app;
// Uncomment for serverless.
// module.exports.handler = serverless(app);
我现在不知道该怎么办。很明显,我的 API 在没有无服务器的情况下也可以正常工作,但我想使用无服务器框架。我想知道这是否与我正在使用的无服务器离线包有关,但我找不到有关该包的二进制数据的任何文档。如果我能得到任何帮助,我将不胜感激。如果还有其他信息我未能提供,请告诉我,我可以发布。谢谢你。
编辑: 根据要求,我上传了两个 PDF,第一个是通过 Nodejs API 正确下载的 PDF,第二个是通过无服务器框架下载的 PDF,导致文件损坏。
可以从以下页面下载 PDF。希望这是允许的。
遗憾的是,我还没有想出解决方案,只是我在使用无服务器的二进制数据损坏方面复制了与您相同的内容(离线以及来自 lambda)。直接使用节点运行应用程序,二进制数据块会正确返回,如果我使用无服务器将其发送回,则该块会损坏。和你一样,我的 serverless.yml 中的提供程序块中有一个类似的块:
apiGateway:
binaryMediaTypes:
- 'application/octet-stream'
我也有同样的问题。我放置了 serverless-apigw-binary 插件,但它不起作用