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

Heroku部署应用图片上传失效,本地运行正常求助

问题描述

我开发了首个大型项目:一款支持用户撰写评论并附带图片发布的博客应用,使用Firebase存储文章。该应用在localhost运行正常,但部署到Heroku后,图片上传功能出现错误(错误截图:图片上传错误截图)。

错误出现在editor.js文件的第8行(fetch请求处),相关代码片段如下:

uploadInput.addEventListener('change', () => {
    uploadImage(uploadInput, "image");
})

const uploadImage = (uploadFile, uploadType) => {
    const [file] = uploadFile.files;
    if(file && file.type.includes("image")){
        const formdata = new FormData();
        formdata.append('image', file);

// 错误发生在这个fetch请求行
        fetch('/upload', {
            method: 'post',
            body: formdata
        }).then(res => res.json())
        .then(data => {
            if(uploadType == "image"){
                addImage(data, file.name);
            } else{
                bannerPath = `${location.origin}/${data}`;
                banner.style.backgroundImage = `url("${bannerPath}")`;
            }
        })
        const change_text = document.getElementById("uploadban");
        change_text.innerHTML = " ";
    } else{
        alert("upload Image only");
    }
}

我怀疑问题源于将文件上传到项目目录的方式,server.js中的相关代码片段如下:

app.post('/upload', (req, res) => {
    let file = req.files.image;
    let date = new Date();
    // 图片名称
    let imagename = date.getDate() + date.getTime() + file.name;
    // 图片上传路径
    let path = 'public/uploads/' + imagename;

    // 执行上传
    file.mv(path, (err, result) => {
        if(err){
            throw err;
        } else{
            // 返回图片上传路径
            res.json(`uploads/${imagename}`)
        }
    })
})

请问是否需要使用AWS S3这类在线存储服务来解决该问题?


问题根源

Heroku的文件系统是临时的——每次应用重启(比如部署新代码、自动扩容、Heroku定期重启),所有上传到本地目录的文件都会被清空。这就是你部署后图片上传失效的核心原因,本地运行正常是因为本地文件系统是持久化的。

解决方案

必须使用云存储服务来存储上传的图片,而不是依赖Heroku的本地文件系统。你有几个可行选择:

  1. AWS S3/Google Cloud Storage等专业云存储
    这是最通用的方案,专门用于持久化存储用户上传的文件。需要修改server.js中的上传逻辑,把文件直接上传到云存储服务,而非本地目录,之后返回云存储的文件URL给前端使用。

  2. 复用已有的Firebase Storage
    既然你已经在用Firebase存储文章,完全可以直接用Firebase Storage存图片。前端可直接将图片上传到Firebase Storage,再把URL关联到Firebase的文章数据;或者后端处理上传逻辑,调用Firebase SDK完成文件存储,流程更统一。

  3. Heroku第三方存储插件
    Heroku市场有很多集成好的存储插件(比如Cloudinary、AWS S3官方插件),可以快速接入,减少手动配置的工作量。

为什么不能用Heroku本地存储?

Heroku的临时文件系统设计是为了保证应用的扩展性和一致性,任何写入本地的文件都不能依赖其持久化存在。即使暂时上传成功,下次应用重启后文件就会消失,用户也无法访问之前上传的图片。

代码修改方向

不管选哪种云存储,核心都是替换file.mv(path, ...)这部分逻辑:

  • 不再将文件写入本地public/uploads目录
  • 改为调用对应云存储的SDK,将文件上传到云端
  • 返回云端的文件URL(而非本地路径)给前端,前端直接使用该URL展示图片

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 14:36:20