我正在嘗試在 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 問題。
P粉4638244102024-03-29 10:02:40
您只需將令牌包含在 formData
中。無需標頭或 cookie 操作:
const onSubmit = async (data) => { const formData = new FormData() formData.append('file', data.file[0]) formData.append('csrfmiddlewaretoken', getCookie('csrftoken')); const res = await axiosInstance.post('/upload/', formData, { timeout: 0, headers: { 'Content-Type': 'multipart/form-data', }, withCredentials: true, }) console.log(res) }
提示:每當您不確定是否正在傳送 cookie、標頭等時,請檢查瀏覽器開發工具中的網頁標籤。如果您在請求的「請求標頭」部分看到它們,那麼它們正在被傳送,這表示問題出在伺服器端。在本例中,對於 multipart/form-data
Django 需要 csrfmiddlewaretoken
表單欄位中的令牌。對於 application/json
請求,您可以使用 X-CSRFToken
標頭。