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

Django从S3获取图片触发UTF-8解码错误UnicodeDecodeError如何解决

问题原因
  • 报错的核心是二进制图片资源无法用UTF-8编码解码:obj['Body'].read()返回的是图片的原始二进制字节流,JPEG、PNG等图片格式的文件头本身就不属于UTF-8的合法字符范围,强转文本必然触发UnicodeDecodeError错误。
  • DRF的Response默认会按照JSON格式处理返回内容,本身就不适合用来返回二进制类的媒体资源。
正确实现

你找到的直接返回二进制流的方案是对的,核心逻辑就是不用对字节流做编码转换,直接用HttpResponse返回二进制内容,同时指定正确的content_type即可。
如果不想写死image/jpeg适配多种图片格式,可以直接读取S3返回的文件类型:

@api_view(['GET'])
def get_image(request, image):
    """Get image link"""
    key = "media/" + str(image)
    s3 = boto3.client('s3', config=Config(signature_version='s3v4', region_name=settings.AWS_S3_REGION_NAME))
    obj = s3.get_object(Bucket=settings.AWS_STORAGE_BUCKET_NAME, Key=key)
    
    image_data = obj['Body'].read()    
    return HttpResponse(image_data, content_type=obj['ContentType'])
可选优化方案

如果站点访问量较高,让所有图片流量都经过Django服务转发会消耗大量服务器资源,你可以选择直接返回S3的预签名访问链接,把下载压力直接转移到S3服务:

@api_view(['GET'])
def get_image(request, image):
    """Get image link"""
    key = "media/" + str(image)
    s3 = boto3.client('s3', config=Config(signature_version='s3v4', region_name=settings.AWS_S3_REGION_NAME))
    presigned_url = s3.generate_presigned_url(
        'get_object',
        Params={'Bucket': settings.AWS_STORAGE_BUCKET_NAME, 'Key': key},
        ExpiresIn=3600
    )
    return redirect(presigned_url)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:24:01