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

Vue.js结合Django REST显示MSSQL二进制图片问题求助

Vue+Django+MSSQL 二进制图片无法显示问题排查与解决

问题背景

我通过用户表单将图片以二进制形式存储到MSSQL数据库,现在需要在用户个人页面展示该图片。技术栈为Vue.js、Django和MSSQL,后端功能正常,但前端图片显示异常。

初始问题:使用GET请求获取图片时,页面仅显示图片占位图标,提示URL无效。

更新后状态

URL无效提示已消失,但图片仍无法显示,且无任何报错信息。我已做以下代码更新:

  • Vue组件中添加:imgElement.src= "data:image/jpeg;base64," + btoa(studentPicUrl);
  • apiservice.js中添加:const imageBlob = new Blob([response_pic.data], { type: 'image/jpeg' });
    MSSQL中图片字段数据类型为image,相关代码如下:

代码片段

views.py

class studentPictures(APIView):
    def get(self, request, cnic, *args, **kwargs):
        try:
            stdpics = StudentPictures.objects.filter(std_cnic=cnic).first()

            # Serialize the StudentPictures instance
            serializer = StudentPicturesSerializer(stdpics)

            return Response(serializer.data, status=status.HTTP_200_OK)
        except StudentPictures.DoesNotExist:
            return Response({"error": "Student Pictures not found"}, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        
    def put(self, request, cnic, *args, **kwargs):
        print("put called", cnic)
        stdpics_data = StudentPictures.objects.filter(std_cnic=cnic).first()

        if stdpics_data is not None:
            image = request.FILES['image']
            file_content = image.read()
            stdpics_data.image= file_content

            serializer = StudentPicturesSerializer(instance=stdpics_data,data= request.data,partial=True)
            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        return Response({"res": "Object does not exist"}, status=status.HTTP_400_BAD_REQUEST)

models.py

class StudentPictures(models.Model):
    std_pic_id = models.AutoField(primary_key=True)
    std_cnic = models.ForeignKey(Student, models.DO_NOTHING, db_column='std_cnic')
    image = models.BinaryField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'student_pictures'

apiservice.js

try {
      const response_pic = await axios.get(`${BASE_URL}/studentpic/${cnic}`, {
        responseType: 'blob',  // Specify responseType as 'blob'
      });

      // Check if the response contains image data
      if (response_pic.data) {
        // Convert the binary data to a Blob object
        const imageBlob = new Blob([response_pic.data]);

        // Create a URL for the Blob
        const imageUrl = URL.createObjectURL(imageBlob);

        // Store the URL in session storage
        sessionStorage.setItem('student_pic_url', imageUrl);
        alert(imageUrl)
      }
    } catch (error) {
      console.error('Error fetching student picture data:', error);
      throw error; // Rethrow the error to handle it in the calling function
    }

Vue组件mounted钩子

mounted() {
    // Check if the session storage exists
    const studentPicUrl = sessionStorage.getItem('student_pic_url');
console.log(studentPicUrl);
    // Set the src attribute of the img element
    const imgElement = document.getElementById('studentImage');
    if (studentPicUrl) {
      // If session storage exists, set the src to the session storage
      imgElement.src = studentPicUrl;
      console.log("image is present");
    } else {
      // If session storage does not exist, set the src to the default image URL
      const defaultImageUrl = require('@/assets/img/default.jpeg'); // Adjust the path accordingly
      imgElement.src = defaultImageUrl;
      console.log("no image");
    }
  }

解决思路

1. 后端返回方式优化(推荐)

当前Django后端返回的是序列化后的JSON数据,二进制图片直接序列化会导致编码丢失,前端无法解析成正确的图片流。修改后端GET接口,直接返回二进制图片响应:

def get(self, request, cnic, *args, **kwargs):
    try:
        stdpics = StudentPictures.objects.filter(std_cnic=cnic).first()
        if not stdpics or not stdpics.image:
            return Response({"error": "Student Pictures not found"}, status=status.HTTP_404_NOT_FOUND)
        # 直接返回二进制图片,指定Content-Type
        return HttpResponse(stdpics.image, content_type='image/jpeg')
    except Exception as e:
        return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

此时前端无需额外处理二进制转Blob,直接用responseType: 'blob'获取后创建ObjectURL即可。

2. 序列化器转Base64处理

如果必须通过JSON返回图片数据,在序列化器中将二进制图片转成Base64字符串:

from base64 import b64encode

class StudentPicturesSerializer(serializers.ModelSerializer):
    image = serializers.SerializerMethodField()

    def get_image(self, obj):
        if obj.image:
            return b64encode(obj.image).decode('utf-8')
        return None

    class Meta:
        model = StudentPictures
        fields = ['image']

前端拿到Base64字符串后,拼接成data URL使用:

// apiservice.js中改为responseType: 'json'
const response_pic = await axios.get(`${BASE_URL}/studentpic/${cnic}`);
if (response_pic.data.image) {
  const imageUrl = `data:image/jpeg;base64,${response_pic.data.image}`;
  sessionStorage.setItem('student_pic_url', imageUrl);
}

3. 前端错误逻辑修正

之前尝试的btoa(studentPicUrl)属于错误操作——studentPicUrl已经是Blob URL,无需转Base64,该操作会破坏URL结构导致图片无法加载,需移除该代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:26:24