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

Django部署至Vercel后无法向AWS S3上传图片问题排查

问题描述

基于Django开发的网站,本地环境可正常上传、查看AWS S3中的媒体图片,但部署到线上(https://django-images-practice.vercel.app/)后,仅能查看S3图片,无法上传新图片,上传时触发以下错误:

ClientError at /
An error occurred (400) when calling the HeadObject operation: Bad Request

错误指向代码中的form_instance.save()行。

相关代码如下:

views.py

def make_and_see(request):
    if request.method == 'POST':
        form_instance = ProductForm(request.POST, request.FILES)
        if form_instance.is_valid():
            form_instance.save()
            messages.success(request, 'Picture is saved')
            return redirect('home')
        else:
            messages.error(request, form_instance.errors)
            return redirect('home')
    else:
        context = {'data': Product.objects.all().order_by('?').first(), 'my_form': ProductForm(), 'time': timezone.now}
        return render(request, 'app1/home.html', context)

settings.py

STORAGES = {"default": {"BACKEND": "storages.backends.s3boto3.S3Boto3Storage"},
            "staticfiles": {"BACKEND": "storages.backends.s3boto3.S3StaticStorage"}}

AWS_ACCESS_KEY_ID = os.environ["MY_AWS_ACCESS_KEY_ID"]
AWS_SECRET_ACCESS_KEY = os.environ["MY_AWS_SECRET_ACCESS_KEY"]
AWS_STORAGE_BUCKET_NAME = '****'
AWS_S3_REGION_NAME = 'ap-south-1'
AWS_QUERYSTRING_AUTH = False
AWS_DEFAULT_ACL = None
AWS_S3_FILE_OVERWRITE = False
AWS_S3_CUSTOM_DOMAIN = f"{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com"

部署环境:网站托管在Vercel,PostgreSQL数据库托管在Railway,已尝试添加AWS_S3_REGION_NAME配置但问题未解决。

排查建议
  • 验证Vercel环境变量配置:确认Vercel后台的MY_AWS_ACCESS_KEY_ID和MY_AWS_SECRET_ACCESS_KEY环境变量是否完全正确,无拼写错误、多余空格或未同步的情况。本地正常运行说明密钥本身有效,但线上可能存在变量配置疏漏。
  • 检查IAM用户权限:确保对应AWS密钥的IAM用户拥有S3的PutObject、HeadObject等核心操作权限,可临时附加AmazonS3FullAccess权限做测试(测试后再细化权限),排除权限不足导致的400错误。
  • 手动指定S3端点:针对ap-south-1区域,在settings.py中添加端点配置:
    AWS_S3_ENDPOINT_URL = "https://s3.ap-south-1.amazonaws.com"
    
    部分区域的默认端点可能存在解析问题,手动指定可避免区域不匹配触发的错误。
  • 调整Vercel上传大小限制:Vercel默认文件上传大小限制为4MB,若上传图片超出该限制会触发请求错误。在项目根目录创建vercel.json并配置:
    {
      "functions": {
        "api/*.py": {
          "maxRequestBodySize": 10485760
        }
      }
    }
    
    上述配置将最大请求体大小设为10MB,可根据实际需求调整。
  • 添加错误日志调试:在views.py中捕获ClientError并打印详细错误信息,便于定位问题:
    from botocore.exceptions import ClientError
    import logging
    
    def make_and_see(request):
        if request.method == 'POST':
            form_instance = ProductForm(request.POST, request.FILES)
            if form_instance.is_valid():
                try:
                    form_instance.save()
                    messages.success(request, 'Picture is saved')
                    return redirect('home')
                except ClientError as e:
                    logging.error(f"S3 Error Details: {e.response['Error']}")
                    messages.error(request, f"Upload failed: {e.response['Error']['Message']}")
                    return redirect('home')
            else:
                messages.error(request, form_instance.errors)
                return redirect('home')
        # 其余代码不变
    
    通过Vercel日志功能查看具体错误详情,能更精准排查问题。
  • 确认存储桶名称正确性:检查AWS_STORAGE_BUCKET_NAME中的桶名是否完全匹配线上配置,避免因桶名拼写错误导致请求到不存在的存储桶触发400错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 04:25:28