1. 原生 JavaScript AJAX
// 前端代码
function sendAjaxRequest() {
const xhr = new XMLHttpRequest();
const url = '/api/data/';
const csrftoken = getCookie('csrftoken'); // 获取 CSRF token
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('X-CSRFToken', csrftoken);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
const response = JSON.parse(xhr.responseText);
console.log('成功:', response);
} else {
console.error('错误:', xhr.status);
}
}
};
const data = JSON.stringify({
'name': '张三',
'age': 25
});
xhr.send(data);
}
// 获取 CSRF token 的辅助函数
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();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
2. 使用 jQuery AJAX
// 前端代码
$(document).ready(function() {
$('#submit-btn').click(function() {
$.ajax({
url: '/api/data/',
type: 'POST',
dataType: 'json',
data: {
'name': $('#name').val(),
'age': $('#age').val(),
'csrfmiddlewaretoken': $('input[name="csrfmiddlewaretoken"]').val()
},
success: function(response) {
console.log('成功:', response);
$('#result').html(response.message);
},
error: function(xhr, status, error) {
console.error('错误:', error);
}
});
});
});
3. 使用 Fetch API(现代推荐)
// 前端代码
async function sendFetchRequest() {
const csrftoken = getCookie('csrftoken');
const url = '/api/data/';
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
body: JSON.stringify({
'name': '李四',
'age': 30
})
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log('成功:', data);
return data;
} catch (error) {
console.error('请求失败:', error);
}
}
4. Django 后端处理
# views.py
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
import json
# 方式1:使用 csrf_exempt(不推荐用于生产)
@csrf_exempt
@require_http_methods(["POST"])
def ajax_example(request):
if request.method == 'POST':
try:
# 处理 JSON 数据
data = json.loads(request.body)
name = data.get('name')
age = data.get('age')
# 处理业务逻辑
result = {
'status': 'success',
'message': f'收到数据:姓名{name},年龄{age}',
'data': data
}
return JsonResponse(result)
except Exception as e:
return JsonResponse({'status': 'error', 'message': str(e)}, status=400)
# 方式2:使用 Django 的 CSRF 保护(推荐)
from django.middleware.csrf import get_token
def get_csrf_token(request):
return JsonResponse({'csrfToken': get_token(request)})
@require_http_methods(["POST"])
def ajax_with_csrf(request):
if request.method == 'POST':
# 从请求头获取 CSRF token
csrf_token = request.headers.get('X-CSRFToken')
# 处理表单数据
name = request.POST.get('name')
age = request.POST.get('age')
# 或者处理 JSON 数据
if request.content_type == 'application/json':
data = json.loads(request.body)
name = data.get('name')
age = data.get('age')
return JsonResponse({
'status': 'success',
'data': {
'name': name,
'age': age
}
})
5. 基于 Django REST Framework(推荐用于复杂 API)
# serializers.py
from rest_framework import serializers
class UserSerializer(serializers.Serializer):
name = serializers.CharField(max_length=100)
age = serializers.IntegerField()
# views.py
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
from django.views.decorators.csrf import csrf_exempt
@api_view(['POST'])
@authentication_classes([])
@permission_classes([AllowAny])
def drf_ajax_view(request):
serializer = UserSerializer(data=request.data)
if serializer.is_valid():
# 处理数据
name = serializer.validated_data['name']
age = serializer.validated_data['age']
return Response({
'status': 'success',
'message': f'用户{name}创建成功',
'data': serializer.data
})
return Response(serializer.errors, status=400)
6. 完整示例:前后端交互
前端 HTML 模板:
<!-- template.html -->
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
{% csrf_token %}
</head>
<body>
<input type="text" id="name" placeholder="姓名">
<input type="number" id="age" placeholder="年龄">
<button id="submit-btn">提交</button>
<div id="result"></div>
<script>
// 自动获取 CSRF token
const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
document.getElementById('submit-btn').addEventListener('click', async () => {
const name = document.getElementById('name').value;
const age = document.getElementById('age').value;
try {
const response = await fetch('/ajax-endpoint/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
body: JSON.stringify({ name, age })
});
const data = await response.json();
document.getElementById('result').textContent = data.message;
} catch (error) {
console.error('Error:', error);
}
});
</script>
</body>
</html>
URL 配置:
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('ajax-endpoint/', views.ajax_endpoint, name='ajax_endpoint'),
path('get-csrf/', views.get_csrf_token, name='get_csrf'),
]
7. 最佳实践建议
CSRF 保护:始终启用 CSRF 保护,通过请求头传递 token
错误处理:在前端和后端都做好错误处理
Content-Type:明确指定请求的内容类型
响应格式:保持 API 响应格式的一致性
使用 DRF:对于复杂的 API,推荐使用 Django REST Framework
异步处理:对于耗时操作,考虑使用 Celery 异步处理
8. 注意事项
- 在生产环境中不要使用
@csrf_exempt
- 验证所有输入数据
- 使用 HTTPS 保护数据传输安全
- 设置合适的 CORS 策略(如果跨域)
- 添加请求频率限制防止滥用
这些方法覆盖了 Django 中 AJAX 请求的主要使用场景,你可以根据具体需求选择合适的方式。