1. juniskw

    Posted

    juniskw
Changes in title
+DjangoページでAjaxしてみる
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,74 @@
+JavascriptでPOSTしようとするとDjangoのCSRF対策に引っかかり失敗してしまうことがあるのだが、公式ドキュメントにちゃんと対策が書かれている。
+http://docs.djangoproject.jp/en/latest/ref/contrib/csrf.html?highlight=csrf#ajax
+
+なお、使い回せるようにコピペしたものをGithubに上げたので使いたい方はどうぞ。
+https://github.com/juniskw/django_tools/blob/master/csrf_token_ajax.js
+
+### 例:POSTした文字に「!!!」を付けてアラートするアプリ。
+
+###### surprise.html
+
+```html+django
+<head>
+ <script type="text/javascript" src="{{STATIC_URL}}js/jquery-1.11.0.min.js"></script>
+ <script type="text/javascript" src="https://raw.githubusercontent.com/juniskw/django_tools/master/csrf_token_ajax.js"></script>
+</head>
+<body>
+ <h1>Let's Surprise!</h1>
+ <form id="surprise_fm" action="surprise/" method="post">
+ <input id="your_txt" type="text" name="your_txt">
+ <input id="surprise_btn" type="button">
+ </form>
+</body>
+<script>
+$(document).ready(function(){
+ $('#surprise_btn').click(function(){ // ボタンクリックでAJAX
+ $.ajax({
+ 'url':$('form#surprise_fm').attr('action'),
+ 'type':'POST',
+ 'data':{
+ 'your_txt':$('#your_txt').val(),
+ },
+ 'dataType':'json',
+ 'success':function(response){ // 通信が成功したら動く処理で、引数には返ってきたレスポンスが入る
+ alert(response.your_surprise_txt); // レスポンスからデータを取り出してアラート
+ },
+ });
+ });
+});
+</script>
+```
+
+###### views.py
+
+```py
+def ajax_test(req): # ビューを表示する関数
+ return render(req,'ajax.html')
+
+def spam(req): # AJAXに答える関数
+ import json
+ from django.http import HttpResponse,Http404
+
+ if req.method == 'POST':
+ txt = req.POST['your_txt'] # POSTデータを取得して
+ surprise_txt = txt + "!!!" # 加工
+
+ response = json.dumps({'your_surprise_txt':surprise_txt,})
+
+ return HttpResponse(response,mimetype="text/javascript") # JSONデータはjavascriptなのか・・
+
+ else:
+ raise Http404 # GETリクエストを404扱いにしているが、実際は別にしなくてもいいかも
+```
+
+なお、jsを以下のように一部書き変えれば普通に **csrf_token** をフォームに入れるだけでも問題ない。
+
+```js
+$.ajax({
+ // ...
+ 'data':$('form#surprise_fm').serialize(),
+ // ...
+});
+```
+
+**serialize** はおそらくform内のinput要素を全て **{name:value,...}** の形にまとめてくれるメソッドだと思われる。Djangoの **csrf_token** はタネを明かせば **hiddenタイプのinput要素** みたいなので、この方法なら通常のフォーム処理と同様に機能することができるのだろう。