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

通过Django Rest返回对象存储图片时UTF-8解码错误的解决方法

解决DRF返回二进制图片时的UTF-8解码错误

这个问题我之前处理过,核心原因是Django Rest Framework的Response类默认会把返回内容当作文本(字符串)处理——它会自动尝试将你的二进制图片数据按UTF-8编码解码成字符串,但图片的二进制开头(比如PNG的0x89)根本不是合法的UTF-8字符,所以直接抛出了解码错误。

下面给你两种靠谱的解决方法:

方法一:用Django原生的FileResponse(推荐)

FileResponse是Django专门用来处理二进制文件的响应类,它不会对字节数据做额外的解码操作,直接把二进制流返回给客户端。你只需要把从Swift拿到的bytes包装成BytesIO类文件对象即可:

from django.http import FileResponse
from io import BytesIO

if request.method == 'GET':
    # 连接Swift存储桶获取图片数据
    conn = swiftclient.client.Connection(**credentials)
    container, file_name = 'container_name', 'object_name'
    _, data = conn.get_object(container, file_name)
    
    # 将bytes转为类文件对象
    image_stream = BytesIO(data)
    # 返回文件响应,指定正确的content-type
    return FileResponse(image_stream, content_type="image/png")

方法二:指定DRF的BinaryRenderer

如果你一定要用DRF的Response,可以通过设置renderer_classes指定使用BinaryRenderer——这个渲染器会直接返回原始字节数据,不会尝试解码:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.renderers import BinaryRenderer

class ImageDownloadView(APIView):
    # 强制使用二进制渲染器
    renderer_classes = [BinaryRenderer]

    def get(self, request):
        conn = swiftclient.client.Connection(**credentials)
        container, file_name = 'container_name', 'object_name'
        _, data = conn.get_object(container, file_name)
        
        # 返回二进制数据,同时指定content-type
        return Response(data, content_type="image/png")

额外提示:动态获取正确的Content-Type

硬编码image/png不够灵活,如果你的存储桶里有多种格式的图片,建议从Swift返回的对象头中获取真实的Content-Type:

headers, data = conn.get_object(container, file_name)
# 从响应头中取content-type,没有的话用默认值
content_type = headers.get('content-type', 'image/png')
# 然后用这个content_type返回响应

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:46:52