在 django 中使用 ajax 时无法发布
Posted
技术标签:
【中文标题】在 django 中使用 ajax 时无法发布【英文标题】:can't post when using ajax in django 【发布时间】:2012-07-31 22:07:37 【问题描述】:所以我一直在关注本教程http://webcloud.se/log/AJAX-in-Django-with-jQuery/,get 方法工作正常。即我得到一个弹出窗口,说明它应该在弹出窗口中说什么。但是,当我使用 post 方法时,我什么也得不到。看来这个请求甚至没有到达我的视野。
这就是我处理这个问题的 javascript 的样子:
$(document).ready(function()
$("#popupbutton").click(function()
$.post("/launch_instances",
name: "Monty",
food: "Spam"
,
function(data)
alert(data);
);
);
...................
这是我模板的相关部分:
<center>
<div id="popupbutton"><input type="submit" value="Launch Instances!" /></div>
</center>
这是我的views.py:
from django.http import HttpResponse
def li_view(request):
return HttpResponse("post gets to the view")
if request.is_ajax():
if request.method == 'GET':
message = "This is an XHR GET request"
elif request.method == 'POST':
message = "This is an XHR POST request"
else:
message = "Nothing"
else:
message = "No XHR"
return HttpResponse(message)
正如您所看到的,当我进入视图时,我做的第一件事是返回一个 HttpResponse,但是当我使用 post 时,我看不到任何弹出窗口,就像我使用 get 时所做的那样。所以我的猜测是,由于某种原因,请求甚至没有到达视图。
这是我的 urls.py:
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^launch_instances/', 'simdata.views.li_view'),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
)
周围也有类似的问题,但没有比这更离奇的了。我是 django/ajax/jquery 的新手,所以可能遗漏了一些非常小的东西。
提前致谢:)
【问题讨论】:
您的urls.py
中有什么内容?可能有bug?
@CypressFrankenfeld 我已经添加了我的 urls.py :)
如果您使用的是现代浏览器,例如最近的 Chrome 或 Firefox(带有 Firebug),您应该能够使用开发人员工具来确定您的请求发生了什么。例如,在 Chrome 中,您应该在触发 AJAX 调用之前打开开发者控制台(Wrench->Tools->Developer Tools)并转到 Network 选项卡。然后你可以看到状态码和响应内容,这应该可以帮助你调试。
在您的 jquery 帖子中,尝试使用“/launch_instances/”而不是“/launch_instances”。
@MichaelC.O'Connor 感谢您提供的出色工具。我的状态文本显示“500 内部服务器错误”,但我没有任何名为响应内容的列
【参考方案1】:
如果您启用了 CSRF,那么简单的 ajax 发布将不起作用。您必须添加 csrf 令牌并将其设置为 ajax 请求标头。
对于 Ajax POST 请求,您必须将 CSRF 令牌作为 POST 数据与每个 POST 请求一起传递。因此,您必须先获取 CSRF 令牌。由于您已启用 CSRF 保护,因此您将从 csrftoken cookie 中获取令牌。 CSRF 令牌 cookie 默认命名为 csrftoken。获取令牌非常简单,可以使用以下代码 sn-p 来实现。
enter code here
function getCSRFCookie()
name = 'csrftoken';
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]);
if (cookie.substring(0, name.length + 1) == (name + '='))
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
return cookieValue;
var csrf_token = getCSRFCookie();
【讨论】:
【参考方案2】:添加 % csrf_token % 后,Django 会创建一个隐藏项,如下所示:
< input type='hidden' name='csrfmiddlewaretoken' value='S1aE7jMFsF24X84CWKf2GxY1UoLzfpf9' / >
因此,当您使用 javascript 发布表单时,隐藏的 csrf_token 也应该发布。尝试将此值与您的 jquery ajax 调用一起添加,如下所示:
$.ajax(
type:'POST',
url: "/some/url/",
data:
username: $("#username").val(),
csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val()
,
)
这应该可以工作。
【讨论】:
【参考方案3】:哦!哇。这是一个很小的错误,我花了一段时间盯着你的代码才发现它。您正在请求/launch_instances
(注意没有末尾的斜杠)。当 Django 遇到这种情况时,它会自动将请求重定向到/launch_instances/
(带有尾部斜杠),但通过重定向,POST 数据被丢弃。添加尾部斜杠,你应该是金色的。
【讨论】:
是的,你是对的。我在查看 chrome 调试器后才意识到这一点,并来这里说。谢谢人:)【参考方案4】:您可能会遇到 Django 的自动 CSRF 保护(对于第一次使用 Django 处理 AJAX 请求的人来说这是一个常见问题)。您可能想查看the documentation on the topic,或者您可以使用@csrf_exempt
装饰器标记您的视图方法(但如果该方法有副作用或可能包含安全数据,则会引入安全问题)。
【讨论】:
我尝试按照教程所说的去做,但它没有让我到任何地方。刚才我在我的方法上方添加了这两行并重新启动了服务器但仍然没有:( from django.views.decorators.csrf import csrf_exempt @csrf_exempt以上是关于在 django 中使用 ajax 时无法发布的主要内容,如果未能解决你的问题,请参考以下文章