You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用AWS Lambda替代EC2托管网站并返回静态文件?

使用Lambda + API Gateway 托管静态文件的解决方案

一、静态文件的存储位置

Lambda是无状态的,但你有两种可靠的方式存储静态文件:

  • 打包进Lambda部署包
    把HTML、JS、CSS、图片等文件和Lambda代码放在同一目录下,一起打包成ZIP文件上传。Lambda执行环境中,这些文件会被放在/var/task/路径下(Node.js环境),可以通过相对路径或绝对路径直接读取。这种方式适合文件体积小、更新不频繁的场景。

  • 存储在S3桶
    如果文件体积较大、需要频繁更新,建议把静态文件存放在S3桶中。Lambda通过AWS SDK读取S3中的文件,无需每次修改文件都重新打包部署Lambda,灵活性更高。


二、Lambda代码实现(Node.js)

方式1:读取部署包内的文件

针对你本地的测试代码,修改为适配Lambda + API Gateway的版本:

const fs = require('fs');
const path = require('path');

exports.handler = async (event) => {
    // 处理根路径请求,默认返回index.html
    const requestPath = event.path === '/' ? '/index.html' : event.path;
    // 拼接Lambda执行环境中的文件绝对路径
    const filePath = path.join('/var/task', requestPath);

    try {
        // 同步读取文件(Lambda中推荐用同步方法,避免异步导致函数提前终止)
        const fileContent = fs.readFileSync(filePath);
        
        // 根据文件后缀设置正确的Content-Type,确保浏览器能正确解析
        let contentType = 'text/plain';
        if (requestPath.endsWith('.html')) contentType = 'text/html';
        else if (requestPath.endsWith('.js')) contentType = 'application/javascript';
        else if (requestPath.endsWith('.css')) contentType = 'text/css';
        else if (requestPath.endsWith('.png')) contentType = 'image/png';
        else if (requestPath.endsWith('.jpg') || requestPath.endsWith('.jpeg')) contentType = 'image/jpeg';

        // 返回符合API Gateway要求的响应格式
        return {
            statusCode: 200,
            headers: { 'Content-Type': contentType },
            body: fileContent.toString('base64'),
            isBase64Encoded: true // 二进制文件(如图片)必须开启此配置
        };
    } catch (err) {
        return {
            statusCode: 404,
            body: 'File not found'
        };
    }
};

方式2:读取S3桶中的文件

先给Lambda的IAM角色添加S3:GetObject权限,然后使用以下代码:

const AWS = require('aws-sdk');
const s3 = new AWS.S3();

exports.handler = async (event) => {
    // 处理请求路径,去掉开头的斜杠作为S3对象的Key
    const requestPath = event.path === '/' ? 'index.html' : event.path.slice(1);
    const bucketName = 'your-static-files-bucket'; // 替换为你的S3桶名

    try {
        // 从S3读取文件
        const s3Object = await s3.getObject({
            Bucket: bucketName,
            Key: requestPath
        }).promise();

        // 使用S3对象自带的Content-Type,或自行判断
        const contentType = s3Object.ContentType || 'text/plain';

        return {
            statusCode: 200,
            headers: { 'Content-Type': contentType },
            body: s3Object.Body.toString('base64'),
            isBase64Encoded: true
        };
    } catch (err) {
        return {
            statusCode: 404,
            body: 'File not found'
        };
    }
};

三、API Gateway配置注意事项

  1. 关联Lambda与API:创建GET方法,集成类型选择Lambda函数,关联你的静态文件处理Lambda。
  2. 开启二进制支持:如果包含图片等二进制文件,需在API Gateway的「设置」中添加对应的媒体类型(如image/png、image/jpeg),否则API Gateway会损坏二进制数据。
  3. 部署API:每次修改配置后,需部署到指定阶段才能通过URL访问。

内容的提问来源于stack exchange,提问作者BigChungus443

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 18:51:19