Javascript 使用JS/Ajax API将通知标记为已读

Javascript 使用JS/Ajax API将通知标记为已读,javascript,ajax,django,notifications,csrf,Javascript,Ajax,Django,Notifications,Csrf,我在我的站点中实现了django通知,它运行得非常好()。 我唯一希望的最后一个问题是,通知从未标记为已读。有可能通过API调用实现这一点,因此我用JS编写了一些东西。我能得到数据,但我不能更改/发布,因为我总是得到403。我可以在管理页面中选中/取消选中布尔值,但我无法使用API调用来执行此操作。有人知道我能做什么吗?“文档”只是Github上的一个站点。制造商只做了一些简短的例子,没有太多的上下文 我的代码: $(".notiBla").click(function(){ $.ajax({

我在我的站点中实现了django通知,它运行得非常好()。 我唯一希望的最后一个问题是,通知从未标记为已读。有可能通过API调用实现这一点,因此我用JS编写了一些东西。我能得到数据,但我不能更改/发布,因为我总是得到403。我可以在管理页面中选中/取消选中布尔值,但我无法使用API调用来执行此操作。有人知道我能做什么吗?“文档”只是Github上的一个站点。制造商只做了一些简短的例子,没有太多的上下文

我的代码:

$(".notiBla").click(function(){
$.ajax({
    url:("/inbox/notifications/api/unread_list/?max=3&mark_as_read=false/"),
    dataType:'json',
    type: 'POST',
    data: "unread_list",
    success:function(response){
      response.unread_list[0].unread=false
      console.log(response.unread_list[0].unread)
    }
});
});
这将返回403,因为不允许im进行POST。当我使用Get时,它会正确显示数据,但这是无用的,因为我需要更改数据。。。 有人知道答案吗?或者知道实现我目标的其他方法吗

好的,我刚刚发现了一条错误消息。它说:

Forbidden (CSRF token missing or incorrect.): /inbox/notifications/api/unread_list/
[05/May/2017 19:38:28] "POST /inbox/notifications/api/unread_list/?max=3&mark_as_read=false/ HTTP/1.1" 403 2502

但是我还是有点迷路,因为我不知道CSRF丢失在哪里。

要向Django视图发送Ajax帖子,需要传递CSRF令牌:将此密钥添加到.Ajax()对象:

Django的
{{csrf_token}
模板变量将输出一个令牌字符串,例如
“mytoken123456789”
。不要与
{%csrf\u token%}
元素中的模板标记相混淆,该标记输出HTML输入元素:

<input type="hidden" name='csrfmiddlewaretoken' value='mytoken123456789' />

要向Django视图发送Ajax帖子,需要传递CSRF令牌:将此键添加到.Ajax()对象:

Django的
{{csrf_token}
模板变量将输出一个令牌字符串,例如
“mytoken123456789”
。不要与
{%csrf\u token%}
元素中的模板标记相混淆,该标记输出HTML输入元素:

<input type="hidden" name='csrfmiddlewaretoken' value='mytoken123456789' />

来自文档:

阿贾克斯

虽然上述方法可用于AJAX POST请求,但也有一些不便:您必须记住在每个POST请求中都要将CSRF令牌作为POST数据传递进来。因此,有一种替代方法:在每个XMLHttpRequest上,将自定义X-CSRFToken头设置为CSRF令牌的值。这通常更容易,因为许多JavaScript框架提供了钩子,允许在每个请求上设置头

首先,您必须获得CSRF令牌。如何做到这一点取决于是否启用了CSRF_USE_SESSIONS设置

如果CSRF_USE_SESSIONS为False,则获取令牌

推荐的令牌源是csrftoken cookie,如果您已如上所述为视图启用CSRF保护,则将设置该cookie

默认情况下,CSRF令牌cookie的名称为csrftoken,但您可以通过CSRF_cookie_name设置控制cookie名称

默认情况下,CSRF头名称为HTTP_X_CSRFTOKEN,但您可以使用CSRF_头名称设置对其进行自定义。 获取代币非常简单:

CSRF令牌也存在于DOM中,但仅当在模板中使用CSRF_令牌显式包含时。cookie包含规范令牌;CsrfViewMiddleware更喜欢cookie而不是DOM中的令牌。无论如何,如果DOM中存在令牌,则保证您拥有cookie,因此您应该使用cookie! 警告

如果视图未呈现包含csrf_令牌模板标记的模板,Django可能不会设置csrf令牌cookie。这在表单动态添加到页面的情况下很常见。为了解决这种情况,Django提供了一个视图装饰器,强制设置cookie:sure\u csrf\u cookie()。 如果CSRF_USE_SESSIONS为True,则获取令牌

如果激活CSRF_USE_会话,则必须在HTML中包含CSRF令牌,并使用JavaScript从DOM读取令牌:

简单地说,只需在js文件中提供getCookie函数并设置csrftoken变量。 然后添加ajaxSetup功能,这就应该实现了。

来自文档:

阿贾克斯

虽然上述方法可用于AJAX POST请求,但也有一些不便:您必须记住在每个POST请求中都要将CSRF令牌作为POST数据传递进来。因此,有一种替代方法:在每个XMLHttpRequest上,将自定义X-CSRFToken头设置为CSRF令牌的值。这通常更容易,因为许多JavaScript框架提供了钩子,允许在每个请求上设置头

首先,您必须获得CSRF令牌。如何做到这一点取决于是否启用了CSRF_USE_SESSIONS设置

如果CSRF_USE_SESSIONS为False,则获取令牌

推荐的令牌源是csrftoken cookie,如果您已如上所述为视图启用CSRF保护,则将设置该cookie

默认情况下,CSRF令牌cookie的名称为csrftoken,但您可以通过CSRF_cookie_name设置控制cookie名称

默认情况下,CSRF头名称为HTTP_X_CSRFTOKEN,但您可以使用CSRF_头名称设置对其进行自定义。 获取代币非常简单:

CSRF令牌也存在于DOM中,但仅当在模板中使用CSRF_令牌显式包含时。cookie包含规范令牌;CsrfViewMiddleware更喜欢cookie而不是DOM中的令牌。无论如何,如果DOM中存在令牌,则保证您拥有cookie,因此您应该使用cookie! 警告

如果视图未呈现包含csrf_令牌模板标记的模板,Django可能不会设置csrf令牌cookie。这在表单动态添加到页面的情况下很常见。为了解决这种情况,Django提供了一个视图装饰器,强制设置cookie:sure\u csrf\u cookie()。 如果CSRF_USE_SESSIONS为True,则获取令牌

如果激活CSRF_使用_会话,则必须在yo中包含CSRF令牌
// using jQuery
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');
var csrftoken = Cookies.get('csrftoken');
{% csrf_token %}
<script type="text/javascript">
// using jQuery
var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
</script>
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}

$.ajaxSetup({
beforeSend: function(xhr, settings) {
    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
        xhr.setRequestHeader("X-CSRFToken", csrftoken);
    }
}
});