You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Django REST Framework通过Ajax登录返回HTML而非JSON问题求助

哦,我懂你遇到的问题了——你用的/api-auth/login/其实是DRF自带的可浏览API登录页面,它本来就是返回HTML的,根本不是给Ajax调用的JSON接口!这就是核心问题所在。

下面给你两个针对性的解决方案,看你更倾向用JWT还是Session认证:


方案1:用JWT自带的JSON登录接口(推荐,因为你已经配置了JWT认证)

rest_framework_jwt已经为你封装好了现成的JSON登录端点,只需要把它加到URL配置里就行:

第一步:配置URL

在你的urls.py中添加:

from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
    # ... 你的其他URL配置
    path('api-token-auth/', obtain_jwt_token),  # 这个就是专门的JSON登录接口
]

第二步:修改Ajax请求

把请求指向新的端点,并且确保请求格式正确:

$.ajax({
    url: '/api-token-auth/',
    method: 'POST',
    contentType: 'application/json',  // 必须指定这个,告诉后端你发的是JSON数据
    data: JSON.stringify({
        username: $('#username').val(),  // 替换成你的用户名输入框选择器
        password: $('#password').val()   // 替换成你的密码输入框选择器
    }),
    success: function(response) {
        // 登录成功后会返回JWT token,比如 response.token
        console.log('登录成功,Token:', response.token);
        // 把Token存在localStorage里,后续请求带上它
        localStorage.setItem('jwt_token', response.token);
        // 之后的API请求可以在headers里加:'Authorization': 'JWT ' + localStorage.getItem('jwt_token')
    },
    error: function(xhr) {
        // 错误信息会以JSON返回,比如用户名密码错误
        console.error('登录失败:', xhr.responseJSON);
    }
});

方案2:自定义Session登录接口(如果你想用Session认证)

如果更倾向于用SessionAuthentication,你需要自己写一个返回JSON的登录视图,因为DRF的默认登录页不支持这个场景:

第一步:写登录视图

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.contrib.auth import authenticate, login

class JSONSessionLoginView(APIView):
    # 登录接口不需要前置认证
    permission_classes = []

    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        
        # 验证用户身份
        user = authenticate(request, username=username, password=password)
        if user:
            login(request, user)
            return Response({
                'message': '登录成功',
                'user_info': {
                    'username': user.username,
                    'email': user.email
                }
            }, status=status.HTTP_200_OK)
        else:
            return Response({
                'error': '用户名或密码错误'
            }, status=status.HTTP_401_UNAUTHORIZED)

第二步:配置URL

path('api-session-login/', JSONSessionLoginView.as_view()),

第三步:修改Ajax请求

这里可以用form-data格式(不用转JSON),注意要带上CSRF token(Session认证需要):

// 先获取CSRF token(Django默认存在cookie里)
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;
}

$.ajax({
    url: '/api-session-login/',
    method: 'POST',
    headers: {
        'X-CSRFToken': getCookie('csrftoken')  // 必须带上这个
    },
    data: {
        username: $('#username').val(),
        password: $('#password').val()
    },
    success: function(response) {
        console.log('登录成功:', response);
        // Session认证下,后续请求会自动带上cookie,不用手动处理token
    },
    error: function(xhr) {
        console.error('登录失败:', xhr.responseJSON);
    }
});

几个小提醒

  • 如果你的前端和后端是跨域名的,还需要配置Django的CORS(不过同域名下不用管)
  • 检查你的REST_FRAMEWORK配置,你已经加了JSONRenderer,这没问题,不用改

内容的提问来源于stack exchange,提问作者Diego Jancic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:17:20