【问题标题】:POST via Ajax with Django使用 Django 通过 Ajax 发布
【发布时间】:2015-11-22 01:54:01
【问题描述】:

基于https://godjango.com/18-basic-ajax/ 我尝试通过 Ajax 和 Django 进行 POST。

我在 GitHub 上创建了一个项目https://github.com/rg3915/front-dj-test

urls.py

url(r'^customer/add$', 'core.views.customer_add', name='customer_add'),
url(r'^customer/save$', 'core.views.customer_save', name='customer_save'),

models.py

class Customer(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()

views.py

import json
from django.shortcuts import render
from django.http import Http404, HttpResponse


def customer_add(request):
    return render(request, 'customer_add.html')


def customer_save(request):
    if request.is_ajax() and request.POST:
        # return HttpResponse('Salvou')
        data = {'message': "%s added" % request.POST.get('item')}
        return HttpResponse(json.dumps(data), content_type='application/json')
    else:
        raise Http404

customer_add.html

<html>
  <body>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>

  <form class="form-horizontal col-sm-4 col-lg-4" method="POST">
    <legend>Cadastrar</legend>
    {% csrf_token %}

    <div class="form-group">
      <label for="id_name">Nome</label>
      <input type="text" id="id_name" name="name" class="form-control">
    </div>

    <div class="form-group">
      <label for="id_email">e-mail</label>
      <input type="text" id="id_email" name="email" class="form-control">
    </div>

    <div class="form-group">
      <div class="col-sm-10 col-sm-offset-2">
      <button type="submit" id="id_submit" class="btn btn-primary">Salvar</button>
      </div>
    </div>
  </form>

  <script>
    $('form').submit(function(event) {
      console.log($( "form" ).serializeArray());
      $.ajax({
        type: 'POST',
        url: '/customer/save',
        data: {"item": $("input").val()},
        dataType: 'json',
        encode: true,
        crossDomain: false,
        beforeSend: function(xhr, settings) {
          if (!csrfSafeMethod(settings.type)) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
          }
        },
        success: function(data){
          console.log(data);
        },
        error: function(){
          // alert('Deu Erro');
          console.log('Deu Erro');
        }
      });
      event.preventDefault();

      // CSRF code
      function getCookie(name) {
        var cookieValue = null;
        var i = 0;
        if (document.cookie && document.cookie !== '') {
          var cookies = document.cookie.split(';');
          for (i; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
              cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
              break;
            }
          }
        }
        return cookieValue;
      }
      var csrftoken = getCookie('csrftoken');

      function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
      }
    });
  </script>

  </body>
</html>

但这给出了一些错误。看下图:

我想知道需要纠正什么才能完美地工作。

【问题讨论】:

  • 如果你能得到错误信息,那会有帮助。另外,试试 ajaxform (github.com/malsup/form) 让事情变得更简单
  • 为什么要使用 ajax 提交表单?你不能只使用 django 形式吗?

标签: python ajax django post django-forms


【解决方案1】:

你需要

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def customer_save(request):
    # ...

【讨论】:

    【解决方案2】:

    你做错了。您发送了一个未定义的crsftoken,因为您在请求之后定义了您的crsftoken 值:var csrftoken = getCookie('csrftoken');

    纠正您的解决方案:

    function getCookie(name) {
      var cookieValue = null;
      var i = 0;
      if (document.cookie && document.cookie !== '') {
        var cookies = document.cookie.split(';');
        for (i; i < cookies.length; i++) {
          var cookie = jQuery.trim(cookies[i]);
          // Does this cookie string begin with the name we want?
          if (cookie.substring(0, name.length + 1) === (name + '=')) {
            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
            break;
          }
        }
      }
      return cookieValue;
    }
    function csrfSafeMethod(method) {
        // these HTTP methods do not require CSRF protection
        return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    $('form').submit(function(event) {
        event.preventDefault();
        console.log($( "form" ).serializeArray());
        $.ajax({
            type: 'POST',
            url: '/customer/save',
            data: {"item": $("input").val()},
            dataType: 'json',
            encode: true,
            crossDomain: false,
            beforeSend: function(xhr, settings) {
                if (!csrfSafeMethod(settings.type)) {
                    xhr.setRequestHeader("X-CSRFToken", getCookie('crsftoken'));
                }
            },
            success: function(data){
                console.log(data);
            },
            error: function(){
                // alert('Deu Erro');
                console.log('Deu Erro');
            }
        });
    });
    

    您还可以在 data 对象中发送 CRSF 令牌。你像处理其他字段一样处理crsftoken,那么你就不需要更多的getCookiecsrfSafeMethod 函数了。这是一个例子:

    // replace with the correct CSS selector of your crsftoken input
    var crsftoken = $('input[name=\'crsftokenmiddleware\']').val()
    $.ajax({
        type: 'POST',
        url: '/customer/save',
        data: {
          'crsftokenmiddleware': crsftoken
          'item': $("input").val()
        },
        dataType: 'json',
        encode: true,
        crossDomain: false,
        success: function(data){
            console.log(data);
        },
        error: function(){
            // alert('Deu Erro');
            console.log('Deu Erro');
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2015-11-04
      • 2014-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-30
      • 2010-10-17
      • 2021-10-18
      • 2015-05-20
      相关资源
      最近更新 更多