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