gpt4 book ai didi

django - CSRF错误Django ajax .post没有表单

转载 作者:行者123 更新时间:2023-12-02 07:19:25 25 4
gpt4 key购买 nike

关于这个主题有很多堆栈溢出问题,我一直在经历这些问题,但没有找到我要找的东西,但如果这是另一个问题的重复,我深表歉意。

我的问题是,我相信我已经为我的 django 项目正确设置了 CSRF cookie,但我收到以下错误(这可能有所不同):

Forbidden (403)

CSRF verification failed. Request aborted. Help

Reason given for failure:

CSRF token missing or incorrect.

使用 firebug,我可以验证我是否从服务器接收了 csrf token ,并且我的 .post 在请求中包含相同的 csrf token 。我知道我的浏览器不是问题,因为我可以查看浏览器的 cookie 并验证浏览器中是否存储了相同的 csrf token 。

views.py:

from django.views.decorators.csrf import ensure_csrf_cookie, csrf_exempt
from django.shortcuts import render_to_response
from django.http import HttpResponse
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.template import RequestContext

def base_view(request):
#Determine data for page

return render_to_response('template.html',{'important_data':important_data}, context_instance=RequestContext(request))

@login_required
def ajax_view(request):
if request.method == u'POST':
#Do some things with database
return HttpResponse('')

模板.html

<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script>
<script src="{{ STATIC_URL }}JS/jquery.js"></script>
</head>
<body>
{% csrf_token %}
<div class="ajax_trigger"></div>
</body>
</html>

jquery.js

$(document).ready(function(){
$(".ajax_trigger").click(function(){
$.post("http://127.0.0.1:8000/ajax",{data:"test"},function(){},'json');
});
});

//code recommended at https://docs.djangoproject.com/en/dev/ref/contrib/csrf/
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;
}
var csrftoken = getCookie('csrftoken');

function csrfSafeMethod(method) {
//these HTTP methods do not require CSRF protection
return(/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function sameOrigin(url) {
// test that a given url is a same-origin URL
// url could be relative or scheme relative or absolute
var host = document.location.host; // host + port
var protocol = document.location.protocol;
var sr_origin = '//' + host;
var origin = protocol + sr_origin;
//Allow absolute or scheme relative URLs to the same origin
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') || (url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative
!(/^(\/\/|http:|https:).*/.test(url));
}

$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
//send the token to same-origin, relative URLs only.
//send the token only if the method warrants CSRF protection
//using the CSRFToken value acquired earlier
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});

settings.py 片段:

MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

如果我将@csrf_exempt添加到我的ajax_view中,那么对post请求的响应将成功。但这不就违背了csrf保护的初衷吗?

我不这么认为Django CSRF check failing with an Ajax POST request有我正在寻找的答案,因为它似乎只适用于旧版本的 django。

感谢任何可以帮助我指明正确方向的人!

更新:此配置适用于 django 1.4,但在 django 1.5+ 上我遇到了一些问题。在查看了 Django 1.5 发行说明 ( https://docs.djangoproject.com/en/dev/releases/1.5/#miscellaneous ) 后,我发现了这一点:“csrf_token 模板标记不再包含在 div 中。如果您需要针对 HTML5 之前的严格 DTD 进行 HTML 验证,则应该在其周围添加一个 div页。”这对任何人都意味着什么吗?另外,我在 django 的文档(https://docs.djangoproject.com/en/dev/ref/contrib/csrf/)中注意到,对于像我这样的页面使用ajax而不使用表单的情况,解决方案是“在发送页面的 View 上使用ensure_csrf_cookie()”。我已经尝试过,但没有注意到有什么不同。

如果有人仍在阅读本文,谢谢。

更新2:如果有人发现我的所有内容的网址有错误,我会感到非常尴尬。可能需要用假名或其他东西注册 djangocon...

url.py

from django.conf.urls import patterns, include, url
from mysite.views import *


# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
url('^$', base_view, {'category' : 'general'}, name='home'),
url('^ajax$', ajax_view),

# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)

最佳答案

尝试添加ensure_csrf_cookie装饰器

from django.views.decorators.csrf import ensure_csrf_cookie

@ensure_csrf_cookie
def ajax_view(request):

并且您不需要在 template.html 中使用 {% csrf_token %}

关于django - CSRF错误Django ajax .post没有表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22523852/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com