0

我的jQuery功能看起来像

$("body").on("submit","form",function(e){
        // do not submit the form
        e.preventDefault();

        // handle everything yourself
        var $form = $(this);
        var title = $form.closest('.video-detail').find('.title').text();
        var entryTitle = $form.find('.input-small').val();
        console.debug(title);
        console.debug(entryTitle);

        // send the data to the server using .ajax() or .post()
        $.ajax({
            type: 'POST',
            url: 'addVideo',
            data: {video_title: title},
        }).done(function(){
            alert('done');
        });
    });

然后我的urls.py样子

urlpatterns = patterns('',
    url(r'^$', home),
    url(r'^done$', done, name='done'),
    url(r'', include('social_auth.urls')),
    url(r'^addVideo$', addVideo)
)

我的views.py样子

@login_required()
@transaction.commit_on_success
def addVideo(request):
    logging.info('add Video request - ' + str(request))
    pass

当我运行我的网络应用程序时,我使用 firebug 调试控制台我看到了错误

my.js (line 96)
POST http://myaap.in/addVideo

403 FORBIDDEN    43ms

然后当我进一步钻取作为回应时,我看到

<div id="summary">
  <h1>Forbidden <span>(403)</span></h1>
  <p>CSRF verification failed. Request aborted.</p>

</div>

<div id="info">
  <h2>Help</h2>

    <p>Reason given for failure:</p>
    <pre>
    CSRF cookie not set.
    </pre>


  <p>In general, this can occur when there is a genuine Cross Site Request Forgery, or when
  <a
  href='http://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ref-contrib-csrf'>Django's
  CSRF mechanism</a> has not been used correctly.  For POST forms, you need to
  ensure:</p>

  <ul>
    <li>Your browser is accepting cookies.</li>

    <li>The view function uses <a
    href='http://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext'><code>RequestContext</code></a>
    for the template, instead of <code>Context</code>.</li>

    <li>In the template, there is a <code>{% csrf_token
    %}</code> template tag inside each POST form that
    targets an internal URL.</li>

    <li>If you are not using <code>CsrfViewMiddleware</code>, then you must use
    <code>csrf_protect</code> on any views that use the <code>csrf_token</code>
    template tag, as well as those that accept the POST data.</li>

  </ul>
  • 我是新手Django,大家web development都在一起,不太明白这意味着什么
  • 请帮助我了解我需要学习什么来解决这个问题

更新

我的表格看起来像

<form class="new-playlist form-inline" onclick="event.stopPropagation()">{% csrf_token %}
     <input type="text" class="input-small">
     <button class="btn btn-danger create-playlist-button" type="submit" disabled="disabled">New</button>
</form>

更新 1 添加来自Django CSRF 的代码检查失败并出现 Ajax POST 请求 后,我看到发布数据为

csrfmiddlewaretoken {{ csrf_token }}
video_title The Who - Who Are You?
Source
video_title=The+Who+-+Who+Are+You%3F&csrfmiddlewaretoken=%7B%7B+csrf_token+%7D%7D

jQuery现在看起来像

// setting up ajaxSetup
$(function(){
    $.ajaxSetup({ 
         beforeSend: function(xhr, settings) {
             function getCookie(name) {
                 var cookieValue = null;
                 if (document.cookie && document.cookie != '') {
                     var cookies = document.cookie.split(';');
                     for (var i = 0; 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;
             }
             if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
                 // Only send the token to relative URLs i.e. locally.
                 xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
             }
         } 
    });
});
// creating new playlist
$(function() {
    // activate "New" buttons if input is not empty
    $('form input[type="text"]').live('keyup', function() {
        var val = $.trim(this.value);
        $(this).next("button").prop('disabled', val.length === 0);
    });

    $("body").on("submit","form",function(e){
        // do not submit the form
        e.preventDefault();

        // handle everything yourself
        var $form = $(this);
        var title = $form.closest('.video-detail').find('.title').text();
        var entryTitle = $form.find('.input-small').val();
        console.debug(title);
        console.debug(entryTitle);      

        // send the data to the server using .ajax() or .post()
        $.ajax({
            type: 'POST',
            url: 'addVideo',
            data: {
                video_title: title,
                csrfmiddlewaretoken: '{{ csrf_token }}'
                },
        }).done(function(){
            alert('done');
        });
    });
});

谢谢

4

2 回答 2

0

尝试使用将结果$form.serialize()作为数据传递给$.ajax(). 只要您{% csrf_token %}在表单模板中的某个位置出现,这将选择表单中的所有值(包括令牌)并发送您的 AJAX 调用。

于 2012-08-04T22:44:19.243 回答
0

Django 试图通过坚持你提供一个 CSRF Token来保护你免受CSRF的伤害。通常 - 如果您通过普通 POST 提交表单 - 它很容易启用,您只需执行以下操作:

<form action="." method="post">{% csrf_token %}

但是因为您使用的是 AJAX,所以它有点复杂。查看 django 文档以获取他们的建议或查看处理该问题的上一个问题

本质上,您需要在使用 AJAX 时手动提供和提交令牌,但最好的解决方案似乎取决于您的 django 版本。

于 2012-08-04T22:36:05.733 回答