Angular 5文件上传遇JSON解析错误 - Django Rest Framework求助
Hey there, let's tackle that JSON parse error you're hitting when uploading files from Angular 5 to Django Rest Framework! The root cause almost always boils down to mismatched request headers or missing parser configuration on the DRF side. Here's how to fix it step by step:
1. Fix the Angular Request Headers
The most common issue is that your existing this.headers is probably setting Content-Type: application/json, which tells DRF to expect JSON data—but you're sending a FormData object instead. Browsers automatically set the correct multipart/form-data header (including the necessary boundary parameter) when you send FormData, so we just need to remove the conflicting JSON content type.
Update your Angular service code like this:
uploadStudentFile(solution_id: number, file: File): Observable<SolutionRealFile> { let url = `${this.url}/solutions/${solution_id}/file_uploads/`; const formData: FormData = new FormData(); formData.append('file_src', file, file.name); // Create a copy of your headers and remove the Content-Type that's forcing JSON const uploadHeaders = this.headers.delete('Content-Type'); return this.httpClient.post<SolutionRealFile>(url, formData, { headers: uploadHeaders }) .pipe( catchError(error => { // Add proper error handling here to debug if needed console.error('Upload error:', error); return throwError(() => error); }) ); }
Note: If your original headers don't have any other critical values (like auth tokens), you can even omit the headers parameter entirely—Angular will let the browser handle it.
2. Ensure DRF is Using the Right Parser
DRF needs to know how to parse multipart form data. By default, it should auto-detect based on the request header, but sometimes explicitly setting the parser avoids edge cases.
For Class-Based Views:
from rest_framework.views import APIView from rest_framework.parsers import MultiPartParser from rest_framework.response import Response class SolutionFileUploadView(APIView): # Explicitly tell DRF to handle multipart form data parser_classes = [MultiPartParser] def post(self, request, solution_id): # Access the uploaded file from request.data uploaded_file = request.data.get('file_src') if not uploaded_file: return Response({"error": "No file provided"}, status=400) # Your logic to save the file to SolutionRealFile model goes here # Example: # solution = Solution.objects.get(id=solution_id) # SolutionRealFile.objects.create(solution=solution, file_src=uploaded_file) return Response({"status": "File uploaded successfully"})
For Function-Based Views:
from rest_framework.decorators import api_view, parser_classes from rest_framework.parsers import MultiPartParser from rest_framework.response import Response @api_view(['POST']) @parser_classes([MultiPartParser]) def upload_solution_file(request, solution_id): uploaded_file = request.data.get('file_src') if not uploaded_file: return Response({"error": "No file provided"}, status=400) # Add your file saving logic here return Response({"message": "File uploaded successfully"})
3. Verify Your Serializer and Model
Double-check that your DRF serializer has a FileField for file_src, and your corresponding model uses models.FileField (or ImageField for images):
# models.py from django.db import models class SolutionRealFile(models.Model): solution = models.ForeignKey(Solution, on_delete=models.CASCADE) file_src = models.FileField(upload_to='solution_files/') # Adjust upload path as needed # serializers.py from rest_framework import serializers from .models import SolutionRealFile class SolutionRealFileSerializer(serializers.ModelSerializer): class Meta: model = SolutionRealFile fields = ['id', 'solution', 'file_src']
Quick Troubleshooting Tips
- Use browser dev tools (Network tab) to inspect the request: Check that the
Content-Typeheader ismultipart/form-data; boundary=...(notapplication/json). - Make sure the form field name (
file_src) matches exactly between your Angular code and DRF backend/serializer. - Test the endpoint with a tool like Postman first: Send a
multipart/form-datarequest with a file to confirm the backend works before debugging Angular.
内容的提问来源于stack exchange,提问作者Max

