Help us understand the problem. What is going on with this article?

DjangoページでAjaxしてみる

More than 5 years have passed since last update.

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
<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="submit">
    </form>
</body>
<script>
$(document).ready(function() {
    $('#surprise_fm').submit(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);  // レスポンスからデータを取り出してアラート
            },
        });
        return false;
    });
});
</script>
urls.py
#...
url(r'^surprise/', 'views.for_ajax'),
#...
views.py
def for_view(req):    # ビューを表示する関数
    return render(req,'surprise.html')

def for_ajax(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,})  # JSON形式に直して・・

        return HttpResponse(response,mimetype="text/javascript")  # 返す。JSONはjavascript扱いなのか・・

    else:
        raise Http404  # GETリクエストを404扱いにしているが、実際は別にしなくてもいいかも

なお、jsを以下のように一部書き変えれば普通に csrf_token をフォームに入れるだけでも問題ない。

$.ajax({
    // ...
    'data':$('form#surprise_fm').serialize(),
    // ...
});

serialize はおそらくform内のinput要素を全て {name:value,...} の形にまとめてくれるメソッドだと思われる。Djangoの csrf_token はタネを明かせば hiddenタイプのinput要素 みたいなので、この方法なら通常のフォーム処理と同様に機能することができるのだろう。

juniskw
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした