我在SO上看到了很多这方面,但没有什么可以解决我的问题。
问题:
启用CSRF中间件后,Django在AJAX表单请求上回复403,说明:
“CSRF cookie未设置。”
在documentation之后,实现了JS功能,设置了自定义“X-CSRFToken”标头。
它按预期工作,从浏览器获取“csrftoken” cookie并将其与AJAX请求一起发布:
x-csrftoken: 1a0u7GCQG0wepZHQNThIXeYpMy2lZOf2
但是回复仍然是403。
尝试过的解决方案:
我已尝试过在SO或网络上找到的所有内容,特别是:
检查是否启用了中间件:
MIDDLEWARE_CLASSES = [
...
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
...
]
启用了Cookie的不同浏览器;
使用@ensure_csrf_cookie
;
在我的模板中设置{% csrf_token %}
;
使用render
快捷方式获取正确的请求上下文;
在CSRF_COOKIE_NAME
;
CSRF_HEADER_NAME
和settings.py
明确设置CSRF_COOKIE_SECURE = False
和CSRF_COOKIE_HTTPONLY = False
;
明确设置CSRF_TRUSTED_ORIGINS
设置;
在开发和生产服务器上进行测试;
在我看来,甚至是request.META["CSRF_COOKIE_USED"] = True
,正如有人建议的那样。
仍然一无所获。
接头
如果我在视图中使用@csrf_exempt
和print(request.META)
,很明显自定义标题“X-CSRFToken”存在于请求中,并根据Django文档进行格式化, “HTTP_”前缀,替换为下划线的连字符,全部为大写:“HTTP_X_CSRFTOKEN”。
更重要的是,它的值与Django设置的cookie匹配。
饼干:
奇怪的是,如果我在我的视图中尝试print(request.COOKIES)
,在页面和表单加载上我可以看到“csrftoken” cookie,但是在AJAX上字典为空请求即可。这可能是问题吗?
迫切希望找到真正的错误。感谢您阅读本文。
答案 0 :(得分:7)
好的,问题很简单:
默认情况下,Fetch API不会发送凭据。根据{{3}}:
Request接口的凭证只读属性表示 用户代理是否应该从其他域发送cookie 跨域请求的情况。这与XHR相似 withCredentials标志,但有三个可用值。
默认为omit
,它永远不会发送Cookie。您只需要将same-origin
添加到fetch()
函数参数:
fetch(formUrl, {
...
credentials: 'same-origin',
...
})
你会很高兴:)