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

Django REST Framework图片上传报Unsupported Media Type错误求助

解决Django REST Framework + Svelte Fetch上传图片的Unsupported Media Type错误

错误核心原因

  1. 手动设置Content-Type请求头:浏览器会自动为FormData生成包含正确boundary的multipart/form-data请求头,手动指定反而会破坏解析逻辑,导致后端无法识别媒体类型。
  2. 请求body错误使用JSON格式:代码中创建了FormData但未实际使用,反而将普通对象转为JSON字符串发送,完全不符合文件上传要求的multipart/form-data格式。
  3. 可能的File对象传递错误:若前端传入的image_url是FileReader生成的base64字符串而非原始File对象,后端也无法解析。

解决步骤

1. 修正前端Fetch请求代码

移除手动设置的Content-Type,直接将FormData实例作为请求body:

export const addProduct = async (product) => {
    const fd = new FormData();
    fd.append("name", product.name);
    // 确保传入的是原始File对象,而非base64字符串
    fd.append("image_url", product.image);

    const response = await fetch(`${URL}/products`, {
        method: "POST",
        headers: {
            Authorization: `token ${localStorage.getItem("auth")}`
            // 移除手动设置的Content-Type,浏览器会自动生成正确的请求头
        },
        body: fd, // 直接传递FormData实例
    })
    return response
}

2. 确保前端传递的是File对象

在Svelte组件中,提交时要传入选中的File对象(即onFileSelected中获取的image变量),而非用于预览的base64字符串:

<script>
    import { addProduct } from './api.js';
    let productName = "";
    let selectedImage = null;
    let previewAvatar = "";

    const onFileSelected = (e) => {
        selectedImage = e.target.files[0];
        // 保留预览逻辑,不影响上传
        const reader = new FileReader();
        reader.readAsDataURL(selectedImage);
        reader.onload = (e) => {
            previewAvatar = e.target.result;
        };
    };

    const handleSubmit = async () => {
        await addProduct({ name: productName, image: selectedImage });
    };
</script>

<div>
    <input type="text" bind:value={productName} placeholder="产品名称" />
    <input type="file" accept="image/*" on:change={onFileSelected} />
    {#if previewAvatar}
        <img src={previewAvatar} alt="预览图" style="width:100px;" />
    {/if}
    <button on:click={handleSubmit}>添加产品</button>
</div>

3. 后端代码优化(可选)

  • 确保序列化器正确配置:
from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['id', 'name', 'image_url', 'user']
        read_only_fields = ['user']  # 将user设为只读,避免前端传入
  • 视图中通过save方法传入用户,替代修改initial_data的写法:
@api_view(['GET', 'POST'])
@permission_classes([IsAuthenticated])
@parser_classes([FormParser, MultiPartParser])
def products(request):
    if request.method == 'POST' and isPermitted(request.user, 'allow_edit_inventory'):
        serializer = ProductSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save(user=request.user)  # 直接传入当前用户
            return Response({'message': "product added"}, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 01:40:21