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

如何解决AWS Lambda加载MongoDB Atlas中PNG到Unity Image的报错问题

解决AWS Lambda返回MongoDB存储的Buffer图片导致的内部服务器错误

我将PNG图片以Buffer形式存在MongoDB Atlas中,之前用Express后端能正常获取,但迁移到AWS Lambda后,Unity项目加载图片时持续提示“Internal Server Error”。

原Express后端代码:

exports.tree = function(req, res, next) {
    Tree.findOne({ level: parseInt(req.params.level) }, "data", function(err, f) {
        if (err || !f) { res.send(""); return; }
        res.contentType("image/png");
        res.send(f.data);
    });
};

当前AWS Lambda函数代码:

import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const {Tree, config} = require('/opt/nodejs/models');
const mongoose = require('mongoose');
mongoose.set('strictQuery', true);
await mongoose.connect(config.DB);

function res(body, type="text/plain"){
   const res = { 
       statusCode: 200,
       isBase64Encoded: false,
       headers: { 
           "Access-Control-Allow-Origin":"*",
           "Content-Type": type 
       },
       multiValueHeader: {},
       body
   };
   return res;
}

export const handler = async(event) => {
   let f = await Tree.findOne({ level: parseInt(event.queryStringParameters.level,10) }, "data");
   if (!f) { return res("");  }
   return res(f.data,"image/png");
};

Unity端请求代码:

...
UnityWebRequest www;
if (l > 30) ll = 30; else ll = l;
if (!T[ll - 1]){
    do  {
            www = UnityWebRequestTexture.GetTexture(Apis.tree+"?level="+ll);
            yield return www.SendWebRequest();
            print(www.downloadedBytes + " Current: " + www.error);
        } while (www.error != null || www.downloadedBytes == 0);
        T[ll - 1] = DownloadHandlerTexture.GetContent(www);
    }
    Tr.GetComponent<Image>().sprite = Sprite.Create(T[ll - 1], new Rect(0f, 0f, T[ll - 1].width, T[ll - 1].height), new Vector2(0.5f, 0.5f), 100f);

问题核心

AWS Lambda返回二进制数据的规则和Express不同:

  • Express可以直接发送Buffer对象作为响应体
  • Lambda要求二进制数据必须转为Base64编码的字符串,同时将isBase64Encoded设为true,否则会把Buffer当成普通字符串处理,导致响应格式错误,触发内部服务器错误。

解决方案

修改Lambda中的响应生成逻辑,针对图片类型做Base64编码处理:

import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const {Tree, config} = require('/opt/nodejs/models');
const mongoose = require('mongoose');
mongoose.set('strictQuery', true);

// 标记数据库连接状态,避免冷启动重复创建连接
let dbConnected = false;

function res(body, type="text/plain"){
   let responseBody = body;
   let isBase64 = false;
   
   // 处理图片类型的二进制Buffer数据
   if (type === "image/png" && Buffer.isBuffer(body)) {
       responseBody = body.toString('base64');
       isBase64 = true;
   }
   
   return { 
       statusCode: 200,
       isBase64Encoded: isBase64,
       headers: { 
           "Access-Control-Allow-Origin":"*",
           "Content-Type": type 
       },
       multiValueHeaders: {}, // 修正原代码拼写错误:multiValueHeader → multiValueHeaders
       body: responseBody
   };
}

export const handler = async(event) => {
   // 确保数据库连接成功
   if (!dbConnected) {
       try {
           await mongoose.connect(config.DB);
           dbConnected = true;
       } catch (err) {
           console.error('数据库连接失败:', err);
           return res('数据库连接错误', 'text/plain');
       }
   }
   
   try {
       const level = parseInt(event.queryStringParameters?.level, 10);
       // 校验level参数合法性,避免无效查询
       if (isNaN(level)) {
           return res('无效的level参数', 'text/plain');
       }
       
       let f = await Tree.findOne({ level }, "data");
       if (!f) { return res("");  }
       
       return res(f.data,"image/png");
   } catch (err) {
       console.error('查询失败:', err);
       return res('服务器内部错误', 'text/plain');
   }
};

额外注意事项

  1. 数据库连接优化:原代码将await mongoose.connect放在模块顶层,Lambda冷启动时可能重复创建连接,移到handler内并添加连接状态判断,避免连接溢出。
  2. 参数校验:增加对event.queryStringParameters.level的合法性校验,避免因参数格式错误导致查询失败。
  3. 错误捕获:添加全局try-catch捕获异常,方便排查问题,同时返回明确的错误信息。
  4. 响应头拼写修正:原代码中multiValueHeader应为multiValueHeaders(复数形式),拼写错误可能导致响应头异常。

内容的提问来源于stack exchange,提问作者Chong Lip Phang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:25:52