在django中,使用Ajax直接发送数据返回403原因是django自带了一个防止跨站请求伪的功能,使用表单发送数据时在表单下面使用csrf_token标签即可,而使用Ajax发送post请求时,csrf_token标签是不会起作用的。
其解决方法有3种:
方法一:在处理改请求的函数前面加上叫做csrf_exempt的装饰器,作用是该url所发送的post请求不再防止跨站请求伪。
@csrf_exempt
def task_ajax(request):
print(request.POST)
data_dict = {"status": True, 'data': [11, 22, 33, 44]}
return HttpResponse(json.dumps(data_dict))
在使用该装饰器前需要导入该装饰器,路径如下:
from django.views.decorators.csrf import csrf_exempt
方法二:注释掉setting.py文件中的以下中间件,用于取消防止跨站请求伪功能,该方法不推荐使用。
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'yuque.middleware.serialization_request.SerializationRequest'
]
方法三:也是官网推荐使用的方法。在请求头中添加上一个X-CSRFToken
,值为CSRF 标记。可以通过一下js获取CSRF标记
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
// 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;
}
const csrftoken = getCookie('csrftoken');
跨站请求伪造保护 | Django 文档 | Django (djangoproject.com)https://docs.djangoproject.com/zh-hans/4.0/ref/csrf/#ajax需要注意的是,这里有一个大坑,安装上面的方法获取并发送后还是会报403,官网文档中也没有提到。通过查看源码发现。使用这个方法发送时还需要配置一个叫CSRF_TRUSTED_ORIGINS的配置项。是一个列表,用于声明安全的url。如:
CSRF_TRUSTED_ORIGINS = ["http://127.0.0.1:8080", 'http://*.0.0.1:8080']
*号表示匹配全部。
更多有关该配置说明: