如何在Heroku上实现图片临时上传并获取临时访问URL
实现方案
方案1:纯前端实现(推荐,无需后端交互)
该方案完全在浏览器端实现,不需要将图片上传到Heroku服务端,最符合你无需持久存储、仅当前页面生效的需求:
- 利用浏览器原生
URL.createObjectURL()API,直接为本地选中的图片文件生成仅当前页面会话有效的临时访问链接 - 页面刷新、关闭后链接自动失效,无需额外清理逻辑
- 不会占用Heroku的存储、带宽资源,响应速度极快
代码示例:
<input type="file" id="imageUpload" accept="image/*"> <img id="preview" alt="图片预览"> <script> const uploadEl = document.getElementById('imageUpload') const previewEl = document.getElementById('preview') uploadEl.addEventListener('change', e => { const file = e.target.files[0] if (!file) return // 生成临时访问URL,可直接用于img标签、canvas绘制等所有当前页面内的逻辑 const tempUrl = URL.createObjectURL(file) previewEl.src = tempUrl // 若需要提前释放内存可主动调用 URL.revokeObjectURL(tempUrl) }) </script>
方案2:后端临时存储(适合需要后端处理图片的场景)
如果你的业务需要先把图片传到后端做裁剪、识别等处理,可以用Django内存存储+临时路由的方式实现:
注意:Heroku的文件系统是临时的,单dyno内的本地文件/内存数据会在dyno重启、扩容后自动清空,且多dyno之间数据不共享,完全符合你无需持久存储的需求。
实现步骤
- 配置Django文件上传处理器,让小文件直接存在内存中,不写入磁盘
- 编写上传接口,接收图片后存储在进程内存的临时字典中,生成唯一标识返回
- 编写临时访问接口,通过唯一标识读取内存中的图片内容返回
代码示例
# settings.py 新增配置 # 限制单文件最大5MB,可根据需求调整 FILE_UPLOAD_MAX_MEMORY_SIZE = 5 * 1024 * 1024 FILE_UPLOAD_HANDLERS = [ "django.core.files.uploadhandler.MemoryFileUploadHandler", ]
# views.py from django.http import JsonResponse, HttpResponse from django.views.decorators.csrf import csrf_exempt import uuid # 全局临时存储,仅存在于当前进程内存中 temp_img_store = {} @csrf_exempt def upload_temp_img(request): if request.method != "POST": return JsonResponse({"code": 400, "msg": "请求方法错误"}, status=400) img_file = request.FILES.get("img") if not img_file: return JsonResponse({"code": 400, "msg": "未上传图片"}, status=400) img_id = str(uuid.uuid4()) temp_img_store[img_id] = { "content": img_file.read(), "content_type": img_file.content_type } return JsonResponse({ "code": 200, "url": f"/temp/img/{img_id}/" }) def get_temp_img(request, img_id): img_info = temp_img_store.get(img_id) if not img_info: return HttpResponse("图片不存在", status=404) return HttpResponse(img_info["content"], content_type=img_info["content_type"])
# urls.py from django.urls import path from . import views urlpatterns = [ # 其他原有路由 path("temp/upload/", views.upload_temp_img, name="upload_temp_img"), path("temp/img/<str:img_id>/", views.get_temp_img, name="get_temp_img"), ]
注意事项
- 不要存储超过10MB的大文件,避免占用过多内存导致Heroku回收进程
- 若应用开启多dyno部署,只有接收上传请求的dyno能访问该临时图片
内容的提问来源于stack exchange,提问作者Artem
相关产品推荐
相关产品推荐

