Django REST Framework图片上传报Unsupported Media Type错误求助
解决Django REST Framework + Svelte Fetch上传图片的Unsupported Media Type错误
错误核心原因
- 手动设置
Content-Type请求头:浏览器会自动为FormData生成包含正确boundary的multipart/form-data请求头,手动指定反而会破坏解析逻辑,导致后端无法识别媒体类型。 - 请求body错误使用JSON格式:代码中创建了
FormData但未实际使用,反而将普通对象转为JSON字符串发送,完全不符合文件上传要求的multipart/form-data格式。 - 可能的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
相关产品推荐
相关产品推荐

