使用Axios上传文件遇阻:Django后端PUT接口前端调用问题
Hey there! Let's figure out why your axios PUT file upload isn't working even though Postman can hit the Django API just fine. I've dealt with this exact headache before, so here are the most common fixes to check:
Postman automatically handles the multipart form format for files, but axios won't do this for you. Django can only parse file uploads from multipart/form-data requests, so you need to explicitly use FormData in your frontend code:
selectFileManually.addEventListener('change', function(event){ event.stopPropagation(); event.preventDefault(); const selectedFile = event.target.files[0]; if (!selectedFile) return; // Exit if no file was picked // Create FormData and append your file const formData = new FormData(); // Important: The key 'file' must match exactly what your Django API expects (check request.FILES['file'] in your view) formData.append('file', selectedFile); axios.put('http://127.0.0.1:8000/api/v1/fileup/', formData, { // Don't manually set Content-Type here! FormData will auto-generate the correct boundary headers: { // Add CSRF token if you're in a same-domain scenario (see point 2) 'X-CSRFToken': getCookie('csrftoken') } }) .then(res => console.log('Upload successful!', res)) .catch(err => console.error('Upload failed:', err.response?.data || err.message)); }); // Helper function to grab CSRF token from cookies (for same-domain requests) function getCookie(name) { let cookieValue = null; if (document.cookie && document.cookie !== '') { const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { const cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; }
If your frontend and Django are running on the same domain (or you're using CORS with credentials), Django's CSRF middleware will block the request unless you include the CSRF token:
- For same-domain: Use the
getCookiefunction above to fetch the token from your browser's cookies and add it to theX-CSRFTokenheader. - For cross-domain (CORS):
- Enable
CORS_ALLOW_CREDENTIALS = Truein your Django settings - Add
PUTtoCORS_ALLOW_METHODS - Set
withCredentials: truein your axios config:
axios.put('http://127.0.0.1:8000/api/v1/fileup/', formData, { withCredentials: true, // Add CSRF header if needed }) - Enable
Even if Postman works, double-check your Django view (especially if you're using Django REST Framework):
- Use
MultiPartParserto handle multipart form data in PUT requests:
from rest_framework.parsers import MultiPartParser from rest_framework.views import APIView from rest_framework.response import Response class FileUploadView(APIView): parser_classes = [MultiPartParser] # Critical for parsing files in PUT requests def put(self, request, *args, **kwargs): uploaded_file = request.FILES.get('file') if not uploaded_file: return Response({'error': 'No file provided'}, status=400) # Your file processing logic here (save to disk, etc.) return Response({'status': 'File uploaded successfully'}, status=200)
For regular Django views (not DRF), you may need to manually parse the PUT request body with MultiPartParser since Django doesn't auto-parse multipart data for PUT by default.
Open your browser's DevTools (F12) and go to the Network tab. Look at your PUT request and check:
- Is the request method actually PUT?
- Does the FormData section show your selected file?
- Are the
X-CSRFTokenandContent-Typeheaders set correctly? - What's the response status code? (403 = CSRF issue, 400 = missing file/wrong field name, 500 = server error)
内容的提问来源于stack exchange,提问作者alpha787

