我正在尝试在 React 应用程序中使用 Axios post 请求将文件上传到 Django 服务器。服务器期望请求标头中包含 CSRF cookie。
该请求已包含我能找到的用于设置 cookie 的所有方法。通过document.cookie
,设置withCredential: true
,并指定Cookie
头。
这是我的 Axios 请求:
const onSubmit = async (data) => { const formData = new FormData() formData.append('file', data.file[0]) const csrftoken = getCookie('csrftoken'); document.cookie = `csrftoken=${csrftoken}` const res = await axiosInstance.post('/upload/', formData, { timeout: 0, headers: { 'Cookie': `csrftoken=${csrftoken}`, 'Content-Type': 'multipart/form-data', 'x-csrftoken': csrftoken, }, withCredentials: true, }) console.log(res) }
这是我的 Django 视图:
def upload_file(request): form = UploadFileForm() if request.method == 'POST': form = UploadFileForm(request.POST, request.FILES) if form.is_valid(): file_id = save_file_to_database(request.FILES['file']) response = JsonResponse({'id': file_id}, status=201) return response else: response = HttpResponse({'message': 'Upload failed'}, status=400) return response return render(request, 'upload.html', {'form': form})
另外,我相信我已经在 settings.py
中正确设置了相关的 Django 设置:
CORS_ORIGIN_WHITELIST = ( "http://localhost:8000", "http://127.0.0.1:5173", ) CSRF_TRUSTED_ORIGINS = [ "http://127.0.0.1:5173" ] SESSION_COOKIE_SAMESITE = 'None'
如何确保 CSRF cookie 包含在请求标头中或以其他方式满足 CSRF 要求?可以肯定的是,如果我们将 @csrf_exempt
添加到视图中,该路由就可以工作,所以它确实应该是一个 CSRF 问题。
您只需将令牌包含在
formData
中。无需标头或 cookie 操作:提示:每当您不确定是否正在发送 cookie、标头等时,请检查浏览器开发工具中的网络选项卡。如果您在请求的“请求标头”部分看到它们,那么它们正在被发送,这意味着问题出在服务器端。在本例中,对于
multipart/form-data
Django 需要csrfmiddlewaretoken
表单字段中的令牌。对于application/json
请求,您可以使用X-CSRFToken
标头。