2016-04-03 7 views
0

AJAX(ちょうどJS、jQueryなし)を介してHTMLフォームをアップロードしようとしています。フォームは、テンプレートによって、csrfトークン、ModelForm、および通常のDjangoフォーム(forms.Form)の3つのコンポーネントを追加して組み立てられます。モデルフォーム{{form.as_p}}はフォームの表示部分を構成しますが、フォーム{{order_form}}はいくつかの非表示フィールドを含みます。私のテンプレートのフォームセクションは次のようになります。DjangoバックエンドでFormData()オブジェクトは常に空です。

<form id="{{ form_id }}" action="javascript:submitThisForm('{{ form_id }}', '/submit_blog_entry/')" method='POST' enctype='multipart/form-data'> 
     {% csrf_token %} 
     {{ form.as_p }} 
     {{ other_form }} 
     <input type='submit' value='SAVE changes' /> 
</form> 

私はすでに(私がいるFormData()がこれを自動的に追加することに別の質問への回答で読む)<form>タグからのenctypeを削除しようとしたが、無駄に。

送信ボタンを押すと、フォームIDとAJAXリクエストに使用するURLを渡して、submitBlodEntryForm()JS関数が呼び出されます。そのJS関数のコードはここにある:

function submitThisForm(form_ID, url){ 

    var submit_form = document.getElementById(form_ID); 
    var formData = new FormData(document.getElementById(form_ID)); 

    httpRequest = new XMLHttpRequest(); 

    if (!httpRequest){ 
     alert("Giving up, cannot create an XMLHTTP instance."); 
     return false; 
    }; 

    var url = "/submit_blog_entry/"; 
    var sendCSRFtoken = "csrfmiddlewaretoken="+String(getCookie('csrftoken')); 
    var sendContent = sendCSRFtoken+"&"+formData; 

    httpRequest.onreadystatechange = alertContents; 
    httpRequest.open('POST', url, true); 
    httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
    //httpRequest.send(); 

    httpRequest.send(sendContent); 
    // alternatively: httpRequest.send(formData); 

} 

AJAX要求がサーバ(Djangoのビュー)によって提出され、受信されます。上記のJSコード(変数sendContent)に示すようにcsrfトークンを手動で追加せずにformDataを送信しても、サーバーがトークンを見つけられないため、403エラーが表示されます。これは、しかし...

私はそれぞれのフォームに受信したデータを結合しようとすると、検証が失敗し、フォームの一部でなければなりません:

form = ThisForm(request.POST) 
if form.is_valid(): 
    #do something 

私はrequest.POSTにあるもの印刷する場合、私は端末で次のように取得します。

<QueryDict: {'[object FormData]': [''], 'csrfmiddlewaretoken': ['token goes here']}> 

明らかに、FormDataオブジェクトは空です。私は私の形で2つの必須のフィールドの2次のエラーを取得するので、私もこれを前提とし(form.errors.as_dataを使用して()):

[ValidationError(['This field is required.'])] 

間違って何をして起こっていますか?私はFormData()が有用なデータを生成しないようなテンプレートを台無しにしましたか?間違ってAJAXリクエストを作成していますか?それとも、サーバー側の問題ですか(これまで何もしていません)。

ありがとう、何か助けていただきありがとうございます!

答えて

0

あなたは2つの問題

  • あなたはFORMDATAを使用して、要求にデータを追加するためにFormData.appendを使用する必要があります。
  • いるFormDataオブジェクトは(自動的に正しく設定されている)要求でマルチパート/フォームデータのコンテンツタイプを使用
... 
var url = "/submit_blog_entry/"; 
formData.append("csrfmiddlewaretoken",getCookie('csrftoken')); 

httpRequest.onreadystatechange = alertContents; 
httpRequest.open('POST', url, true); 
//httpRequest.send(); 

httpRequest.send(formData); 
... 
+0

ありがとうございます。私はまたあなたのコードスニペットに示唆されているように、前もってやり直してみました。どちらもうまくいきません。フォームを渡さずに空のFormData()オブジェクトを作成してこれを追加しても、csrfトークンは(403エラーが再び発生しません)。 –

0

このよういるFormDataにフォーム要素を通過しない方が良いかもしれません。

new FormData(document.getElementById(form_ID)) 

私はほとんど確実です、それはFirefoxでのみサポートされています。他のブラウザはオブジェクトを自動入力しません。

また、あなたはここで

var sendContent = sendCSRFtoken+"&"+formData; 

「sendCSRFtoken」の文字列であるので、それは上の「[いるFormDataオブジェクト]」あなたが得る理由です、FORMDATAに対してtoString()メソッドを呼び出し、2を連結ジャンゴ側。この作品は、使用してフォームフィールドを追加作成する

一つの方法:

formData.append(name, value); 

トークンCRSFために同じことを行い、その後、次のように送って呼び出す:

httpRequest.send(formData); 

XMLHttpRequestが、送信のために複数のオーバーロードがありますhttps://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#send()

デバッグ時に、ネットワークタブをchrome deveで開いておくと便利ですクライアント側を除外する前に、何がポストされるかを確認するためのajax呼び出しの前に、loperツールを使用してください。

0

ありがとうございます。私は今問題を見つけた、愚かなコピー&ペースト。 AJAXリクエストを作成するJS関数のsubmitBlogEntryForm()が悪いです。 httpRequestヘッダーの設定

httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 

は、矛盾したエンコード命令を引き起こしました。私はこの行を完全に削除し、テンプレートのformタグに "enctype"を指定しないようにして、FormData()によって自動的に設定されるようにしました。今それは動作します!

もう一度お手数をおかけします。

関連する問題