舟山市分类吧

Django使用AJAX向服务器发起请求的操作方法

2026-03-27 12:47:01 浏览次数:0
详细信息

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. 注意事项

这些方法覆盖了 Django 中 AJAX 请求的主要使用场景,你可以根据具体需求选择合适的方式。

相关推荐