Vue.js非CLI环境下调用REST API获取数据失败求助
问题排查与修复方案
1. Django后端API返回格式错误(核心问题)
你的TaskViewSet使用了TemplateHTMLRenderer,这会让API接口返回渲染后的HTML页面,而非Vue所需的JSON数据。Vue调用http://localhost:8000/api/tasks/时拿到的是整个list.html的内容,不是任务数据的JSON,自然无法渲染。
修复方法:
方案一:拆分视图(推荐,前后端职责分离)
- 单独写返回HTML的视图:
from django.views.generic import TemplateView class TaskListView(TemplateView): template_name = 'list.html'
- 单独写返回JSON的API ViewSet:
from rest_framework import viewsets class TaskAPIViewSet(viewsets.ModelViewSet): queryset = Task.objects.all() serializer_class = TaskSerializer # 默认使用JSONRenderer,无需额外配置
在urls.py中分别配置路由:
path('tasks/', TaskListView.as_view()), # 返回HTML页面 path('api/tasks/', TaskAPIViewSet.as_view({'get': 'list'})), # 返回JSON数据
方案二:让ViewSet支持多渲染器
若要保留一个ViewSet,修改渲染器配置,使其根据请求头返回对应格式:
from rest_framework.renderers import TemplateHTMLRenderer, JSONRenderer class TaskViewSet(ModelViewSet): renderer_classes = [TemplateHTMLRenderer, JSONRenderer] template_name = 'list.html' queryset = Task.objects.all() serializer_class = TaskSerializer def list(self, request): queryset = self.get_queryset() serializer = self.get_serializer(queryset, many=True) if request.accepted_renderer.format == 'html': return Response({'serializer': serializer.data}, template_name=self.template_name) else: return Response(serializer.data)
2. Vue前端代码问题
(1)v-for使用位置错误
你把v-for放在了Vue根元素#app上,会导致整个根组件被重复渲染,不符合Vue规范。应将循环放在根元素内部的子元素上:
<div id="app"> <div v-for="task in tasks" :key="task.id"> {{ task.title }} <!-- 替换为Task模型的实际字段,如title、content等 --> </div> </div>
注意给v-for元素添加:key,避免渲染警告。
(2)重复引入vue-resource
代码中重复引入了两次vue-resource,删除其中一个即可:
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-resource/1.3.4/vue-resource.min.js" integrity="sha256-OZ+Xidb5+lV/saUzcfonHJQ3koQncPy0hLjT8dROdOU=" crossorigin="anonymous"></script>
(3)错误处理不够详细
原代码的console.log(error)无法显示有效错误信息,修改为:
catch (error) { console.log('请求错误:', error.message); if (error.response) { console.log('响应状态:', error.response.status); console.log('响应内容:', error.response.data); } }
(4)模板变量错误
原代码用{{task.data}},但后端返回的JSON中,每个task是Task模型的字段对象,需根据TaskSerializer定义的字段修改,比如task.title、task.description等。
3. 跨域问题(CORS)
若前端页面通过本地文件打开(file://协议),或运行在与Django不同的端口,会被浏览器阻止跨域请求。
修复方法:
在Django中安装并配置django-cors-headers:
- 安装包:
pip install django-cors-headers
- 在settings.py中添加配置:
INSTALLED_APPS = [ # ... 'corsheaders', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', # 放在最前面 'django.middleware.common.CommonMiddleware', # ... ] # 开发环境允许所有域名跨域,生产环境需指定具体域名 CORS_ALLOW_ALL_ORIGINS = True
内容的提问来源于stack exchange,提问作者Rishi Gupta
相关产品推荐
相关产品推荐

