django 和 ajax 的 http 403 错误

发布于 2024-11-25 05:28:33 字数 1275 浏览 0 评论 0原文

我正在研究“Django 1.0 网站开发”,并在使用表单时遇到了问题。服务器抱怨有关“csrf”的问题。我可以通过在表单标签后面添加 {% csrf_token %} 来解决这个问题。我已经阅读了 djangoproject.com 上的文档,但我必须承认我并不完全理解这里到底发生了什么。我不使用中间件类。

当我接触到 ajax 时,真正的问题就开始了。我严格按照书中的说明进行操作,但服务器开始抱怨:

"POST /save/?ajax HTTP/1.1" 403 2332

这是可能导致麻烦的代码:

function bookmark_save() {
var item = $(this).parent();
var data = {
    url: item.find("#id_url").val(),
    title: item.find("#id_title").val(),
    tags: item.find("#id_tags").val()
};
$.post("/save/?ajax", data, function (result) {
    if (result != "failure") {
        item.before($("li", result).get(0));
        item.remove();
        $("ul.bookmarks .edit").click(bookmark_edit);
    }
    else {
        alert("Failed to validate bookmark before saving.");
    }
});
return false;

}

'/save/&ajax' 正在处理,

if ajax:
    return render_to_response('bookmark_save_form.html', variables)

这里的 bookmark_save_form.html:

<form id="save-form" method="post" action="/save/">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="save" />
</form>

据我了解事情,我必须通过 POST 请求传递 csrf_token。但我不知道怎么做。

对此有任何建议都会很棒。

I'm working my way through 'Django 1.0 Web Site Development' and encountered a problem when using forms. The server complained about something concerning 'csrf'. I could solve it by adding {% csrf_token %} right after the form-tag. I already read the documentation at djangoproject.com but I have to admit that I don't fully understand what exactly is happening here. I don't use the middleware classes.

The real problem started when I got to ajax. I followed the instructions in the book to the letter but the server started complaining:

"POST /save/?ajax HTTP/1.1" 403 2332

Here is the code that might cause the trouble:

function bookmark_save() {
var item = $(this).parent();
var data = {
    url: item.find("#id_url").val(),
    title: item.find("#id_title").val(),
    tags: item.find("#id_tags").val()
};
$.post("/save/?ajax", data, function (result) {
    if (result != "failure") {
        item.before($("li", result).get(0));
        item.remove();
        $("ul.bookmarks .edit").click(bookmark_edit);
    }
    else {
        alert("Failed to validate bookmark before saving.");
    }
});
return false;

}

'/save/&ajax' is being handled by

if ajax:
    return render_to_response('bookmark_save_form.html', variables)

Here the bookmark_save_form.html:

<form id="save-form" method="post" action="/save/">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="save" />
</form>

As far as I understand things, I have to pass a csrf_token with the POST request. But I don't have a clue how.

Any advise on this would be great.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

若水般的淡然安静女子 2024-12-02 05:28:33

顺便说一句,我目前也在阅读这本书,并遇到了完全相同的问题。也不是第一次了!本质上发生的情况是 csrf 令牌没有通过 Ajax 请求传递。因此,简短的答案是您需要在 ajax 调用中包含 csrf 令牌。这是通过以下代码块完成的:https://docs.djangoproject。 com/en/1.3/ref/contrib/csrf/#ajax

jQuery(document).ajaxSend(function(event, 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;
}
function sameOrigin(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 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));
}
function safeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
    xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
});

然后我将其作为 .js 文件包含在我的 user_page.html 中。之后,我就可以不受惩罚地进行 Ajax 调用了!

I am currently working through this book as well and ran into the exact same problem, BTW. Not for the first time either! Essentially what is happening is that the csrf token is not being passed via the Ajax request. So, the short and simple answer is that you need to include the csrf token is your ajax call. This is accomplished via this code block: https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/#ajax

jQuery(document).ajaxSend(function(event, 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;
}
function sameOrigin(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 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));
}
function safeMethod(method) {
    return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

if (!safeMethod(settings.type) && sameOrigin(settings.url)) {
    xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
});

I then included this as a .js file in my user_page.html. After that, I could make Ajax calls with impunity!

随梦而飞# 2024-12-02 05:28:33

我从一个已经完成的项目中提取了这个。这是一个联系表单模板。请注意,这是针对 django 的。另请参阅 django 书籍 http://www.djangobook.com/en/2.0/ .我所有的疑问都在这本书中得到了解答。它涵盖了一切。这准确地显示了如何放入 csrf 令牌(在模板中):

<head> 
    <title>Contact Us</title> 
</head> 
<body> 
    <h1>Contact us</h1> 

{% if form.errors %}
    <p style="color: red;"> 
        Please correct the error{{ form.errors|pluralize }} below.
    </p> 
{% endif %}

<form action="" method="post"> 
    {% csrf_token %}
    <ul> 
        {{ form.as_ul }}
    </ul> 
    <input type="submit" value="Submit"> 
</form> 
</body> 

另外,将您的值更改为提交而不是保存,并且使用 post 代替 /save/ 进行操作......这可能会使其工作。

I pulled this from a project already done. This is a contact form template. Mind you this is for django. Also please refer to the django book http://www.djangobook.com/en/2.0/ . All my questions have been answered by this book. It goes over everything. This shows exactly how to put in the csrf token (in a template):

<head> 
    <title>Contact Us</title> 
</head> 
<body> 
    <h1>Contact us</h1> 

{% if form.errors %}
    <p style="color: red;"> 
        Please correct the error{{ form.errors|pluralize }} below.
    </p> 
{% endif %}

<form action="" method="post"> 
    {% csrf_token %}
    <ul> 
        {{ form.as_ul }}
    </ul> 
    <input type="submit" value="Submit"> 
</form> 
</body> 

Also, change your value to submit instead of save, and instead of /save/ for action use post.....that might make it work.

夏末染殇 2024-12-02 05:28:33

我正在阅读这本书,刚刚遇到了同样的问题。这是最简单的解决方案,它的好处是不禁用 Django 的 csrf 保护或必须包含装饰器或摆弄像“ensure_csrf_cookie”这样的实用程序。它只是传递令牌:

在您创建的用于保存自定义 jquery 脚本的 .js 文件中,将以下对添加到 bookmark_save() 函数中的“data”变量中:

csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].val()

因此生成的 bookmark_save 函数如下所示:

function bookmark_save() {
    var item = $(this).parent();
    var data = {
        url: item.find("#id_url").val(),
        title: item.find("#id_title").val(),
        tags: item.find("#id_tags").val(),
        csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].val()
    };
    $.post("/save/?ajax", data, function (result) {
        if (result != "failure") {
            item.before($("li", result).get(0));
            item.remove();
            $("ul.bookmarks .edit").click(bookmark_edit);
        }
        else {
            alert("Failed to validate bookmark before saving.");
        }
    });
    return false;
}

I am working through the book and just ran into the same problem. Here is the simplest solution, which has the benefit of not disabling Django's csrf protection or having to include decorators or fiddle with utilities like 'ensure_csrf_cookie'. It simply passes the token:

In the .js file you created to hold your custom jquery scripts, add the following pair to your 'data' var in in your bookmark_save() function:

csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].val()

So the resulting bookmark_save function looks like this:

function bookmark_save() {
    var item = $(this).parent();
    var data = {
        url: item.find("#id_url").val(),
        title: item.find("#id_title").val(),
        tags: item.find("#id_tags").val(),
        csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].val()
    };
    $.post("/save/?ajax", data, function (result) {
        if (result != "failure") {
            item.before($("li", result).get(0));
            item.remove();
            $("ul.bookmarks .edit").click(bookmark_edit);
        }
        else {
            alert("Failed to validate bookmark before saving.");
        }
    });
    return false;
}
听风念你 2024-12-02 05:28:33

从 django.views.decorators.csrf 导入 csrf_exempt

@csrf_exempt
def my_view(request):
...

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_view(request):
...
万劫不复 2024-12-02 05:28:33

创建一个 JavaScript 文件。我不知道如何格式化代码 - 抱歉。然后在Jquery之后加载它。

此处进行了描述

Create a Javascript file. I do not know how to format the code - sorry. Then load it after Jquery.

It is described here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文