Django Rest Framework + ReactJS:我的 API 有啥问题?

Posted

技术标签:

【中文标题】Django Rest Framework + ReactJS:我的 API 有啥问题?【英文标题】:Django Rest Framework + ReactJS: Whats wrong with my API?Django Rest Framework + ReactJS:我的 API 有什么问题? 【发布时间】:2019-01-24 08:35:37 【问题描述】:

我正在尝试使用“ReactJS”从django rest-framework API 获取数据,但我一直面临同样的错误:

SyntaxError:“JSON.parse:JSON 数据的第 1 行第 1 列出现意外字符”

我认为实际问题出在我的 API 中,因为我已经尝试了 3 种不同的方法将数据导入 React。也许有人知道我可以对我的 API 做些什么来使其工作?我正在使用djangorestframework 库。 API 如下所示:


"questions":"http://127.0.0.1:8000/api/questions/?format=json",
"choices":"http://127.0.0.1:8000/api/choices/?format=json"

我用来检索数据的React Component 如下:

import React,  Component  from 'react';

class ApiFetch extends Component 
  state = 
    data: []
  ;

  async componentDidMount() 
    try 
      const res = await fetch('127.0.0.1:8000/api/?format=json');
      const data = await res.json();
      this.setState(
        data
      );
      console.log(this.state.data)  
     catch (e) 
      console.log(e);  //SyntaxError: "JSON.parse: unexpected character at line 1 column 1 of the JSON data"
    
  
  
  render() 
    return (
      <div>
        (this.state.data)
      </div>
    );
  


export default ApiFetch;

API 的 Header 如下所示:

allow →GET, HEAD, OPTIONS
content-length →123
content-type →application/json
date →Fri, 17 Aug 2018 11:01:36 GMT
server →WSGIServer/0.2 CPython/3.6.3
vary →Accept, Cookie
x-frame-options →SAMEORIGIN

我在我的客户端上尝试了以下示例 API,它成功了: https://jsonplaceholder.typicode.com/todos/1

所以关于 djangorestframework 和我的客户端一定是不兼容的。

【问题讨论】:

带有响应头和请求头的完整响应会更有帮助。 @noel 请在有空时附上它们 我能够在控制台中打印的响应如下。 codeResponse ​ bodyUsed: true ​ headers: Headers ​​ : HeadersPrototype append: append(), delete: delete(), get: get(), ... ok: true ​ redirected: false ​ status : 200 ​ statusText: "OK" ​ type: "basic" ​ url: "localhost:3000/127.0.0.1:8000/api/?format=json" ​ : ResponsePrototype clone: clone(), arrayBuffer: arrayBuffer(), blob: blob(), ... @ 987654331@ 我不确定如何获取标头,但我的服务器记录了这个:code[17/Aug/2018 10:52:49] "GET /api/ HTTP/1.1" 200 99code DRF 通常会在您收到错误服务器端 (404, 500...) 时返回 html 内容,然后您的客户端 JSON 无法解析,从而为您提供所看到的错误消息。为了帮助你调试,你能把url.py和你的views.py的相关部分显示出来吗? 【参考方案1】:

您似乎没有查询到有效的路线,不妨试试以下方法:

async componentDidMount() 
    try 
      const res = await fetch('127.0.0.1:8000/api/questions/?format=json');
      const data = await res.json();
      this.setState(
        data
      );
      console.log(this.state.data)  
     catch (e) 
      console.log(e);  //SyntaxError: "JSON.parse: unexpected character at line 1 column 1 of the JSON data"
    
  

【讨论】:

这里的目标是得到一个如下所示的 javascript 对象:code data = "questions":"127.0.0.1:8000/api/questions/?format=json", "choices":"127.0.0.1:8000/api/choices/?format=json" code我首先尝试让它与这个更简单的 api 一起工作。 你能在将 res 常量解析为 json 之前对其进行 console.log 吗? 它记录:codeResponse 类型:“basic”,url:“localhost:3000/127.0.0.1:8000/api/?format=json”,重定向:false,状态:200,ok:true,statusText:“OK”,标题:标头,bodyUsed: false code【参考方案2】:

解决方案:需要添加跨域资源共享(CORS)

这里的问题是,浏览器会根据同源策略阻止 Javascript 访问其他域。

Django 中的默认解决方法是“django-cors-headers”。 要安装它:

pip install django-cors-headers

然后就可以在settings.py激活了

写作:

INSTALLED_APPS = (
    ##...
    'corsheaders'
)
MIDDLEWARE_CLASSES = (
    'corsheaders.middleware.CorsMiddleware',
    #...
)

CORS_ORIGIN_ALLOW_ALL = True

【讨论】:

以上是关于Django Rest Framework + ReactJS:我的 API 有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章

Django中rest_framework的APIView,序列化组件和视图组件

在 django-rest-framework 中插入 django-allauth 作为端点

Django中rest_framework的认证组件,权限组件,频率组件,序列化组件的最简化版接口

Django Rest Framework 反向和 SimpleRouter

Django Rest Framework组件:解析器JSONParserFormParserMultiPartParserFileUploadParser

根据请求类型更改 Django REST Framework ModelSerializer 中的字段?