amazon-web-services - 使用 express.static 时如何在 aws lambda 和 aws sam 中不返回 json
问题描述
我正在使用 aws lambda 和 aws 的 sma cli 工具制作一个无服务器网站(主要是为了测试向 api 发出真实请求)。我想使用 express.static 函数提供资产,但有问题。当我使用它时,我收到一个关于它不返回 json 的错误,错误说它需要这样做才能工作。我现在有 2 个功能:视图(提供 ejs 文件)和资产(提供静态文件,如 css 和前端 js)。这是我的template.yml:
# This is the SAM template that represents the architecture of your serverless application
# https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template-basics.html
# The AWSTemplateFormatVersion identifies the capabilities of the template
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/format-version-structure.html
AWSTemplateFormatVersion: 2010-09-09
Description: >-
[Description goes here]
# Transform section specifies one or more macros that AWS CloudFormation uses to process your template
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-section-structure.html
Transform:
- AWS::Serverless-2016-10-31
# Resources declares the AWS resources that you want to include in the stack
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html
Resources:
assets:
Type: AWS::Serverless::Function
Properties:
Handler: amplify/backend/function/assets/src/index.handler
Runtime: nodejs14.x
MemorySize: 512
Timeout: 100
Description: serves the assets
Events:
Api:
Type: Api
Properties:
Path: /assets/{folder}/{file}
Method: GET
views:
Type: AWS::Serverless::Function
Properties:
Handler: amplify/backend/function/views/src/index.handler
Runtime: nodejs14.x
MemorySize: 512
Timeout: 100
Description: serves the views
Events:
Api:
Type: Api
Properties:
Path: /
Method: GET
Outputs:
WebEndpoint:
Description: "API Gateway endpoint URL for Prod stage"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
还有我的资产函数代码:index.js:
const awsServerlessExpress = require('aws-serverless-express');
const app = require('./app');
const server = awsServerlessExpress.createServer(app);
exports.handler = (event, context) => {
console.log(`EVENT: ${JSON.stringify(event)}`);
return awsServerlessExpress.proxy(server, event, context, 'PROMISE').promise;
};
应用程序.js:
const express = require('express'),
app = express()
app.use(express.json())
app.use('/assets', express.static('assets'))
app.listen(3000);
module.exports = app
是否有一些我应该知道的 template.yml 配置选项或者我必须更改我的代码?
解决方案
我在 node js 中使用 fs 制作了自己的解决方案。我在视图函数中做了一个简单的代码,如下所示:
app.get('/assets/*', (req, res) => {
if (!fs.existsSync(__dirname + `/${req.url}`)) {
res.sendStatus(404).send(`CANNOT GET ${req.url}`);
return;
}
res.send(fs.readFileSync(__dirname + `/${req.url}`, 'utf-8'));
})
我还编辑了 template.yml 以使其路径为 /assets/{folder}/{file} 的 api 用于视图函数,并删除了 assets 函数并将包含所有资产的 assets 文件夹移动到 views 函数目录
编辑:对于某些 resson 的几乎所有内容,内容类型 http 标头始终设置为 text/html,但是将代码更改为此可以修复它:
app.get('/assets/*', (req, res) => {
if (!fs.existsSync(`${__dirname}${req.url}`)) {
res.sendStatus(404).send(`CANNOT GET ${req.url}`);
return;
}
res.contentType(path.basename(req.url))
res.send(fs.readFileSync(__dirname + `${req.url}`, 'utf-8'));
})
所有这些都是在 res 对象上使用 contentType 函数。您只需传入文件名,它就会自动找到正确的内容类型。
推荐阅读
- android - 当其他应用程序不遵守焦点丢失策略时如何处理音频焦点
- angular - 如何在 Ionic 4 中调整标签大小?
- c# - Cosmos DB - 在 LINQ 中使用 ARRAY_CONTAINS
- spring-cloud-dataflow - Spring Cloud Dataflow 容器任务部署的错误?
- c# - 向现有客户添加信用卡来源时出现问题
- python-3.x - python3中的简单和复合年度投资计算器
- python - 检查发布 Paho MQTT Python 的连接
- ms-access - 访问错误:ORDER BY 表达式包含查询未选择的字段
- android - 在 Android 库 AAR 中使用 Volley 时找不到字节码
- wpf - 创建多个扩展控件