Django Rest Framework CORS 阻止 XMLHttpRequest

Posted

技术标签:

【中文标题】Django Rest Framework CORS 阻止 XMLHttpRequest【英文标题】:Django Rest Framework CORS blocking XMLHttpRequest 【发布时间】:2019-08-02 03:41:39 【问题描述】:

我使用 Django-cors-headers 设置了我的 CORS 策略,并具有以下设置:

APPEND_SLASH=False
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = (
    'localhost:8000',
    'localhost:3000',
    'localhost'
)

我还把它添加到了 installed_apps 和中间件中。

现在我正在为前端制作一个 React 应用程序,并使用 AXios 来处理我的 API 请求。当我发出 API 请求以登录我的应用程序时,CORS 策略允许它。但是,如果我发出需要令牌的 API 请求,我会得到:

从源“http://localhost:3000”访问“localhost:8000/api/TestConnection/”处的 XMLHttpRequest 已被 CORS 策略阻止:跨源请求仅支持协议方案:http、data、chrome、chrome-extension ,https。

似乎我需要为支持的协议方案允许 XMLHttpRequest,但我在 pypi 文档中找不到任何关于此的内容。

编辑: 这是 AXIOS 请求:

axios.post("localhost:8000/api/TestConnection/",
    headers:
      
          'Authorization': "Bearer " + localStorage.getItem('JWTAccess')
      
    ,
     
      testString: 'Hello API'
    )
    .then(response => 
      console.log(response)
      )
    .catch(error => 
      console.log(error);
)

谢谢!

【问题讨论】:

它是否适用于 CORS_ORIGIN_ALLOW_ALL = False? 【参考方案1】:

我在 ReactNative 应用程序中遇到了类似的问题,这是由于 ReactNative 使用 IP 10.0.2.2 作为 localhost(我不记得细节或原因)。我通过添加到我的班级解决了它。

  componentWillMount() 
    axios.defaults.baseURL = 'http://10.0.2.2:8000/api/';
    axios.defaults.timeout = 1500;
  

我不知道这是否是正确的 IP,但可能值得一看。

编辑

handleRequest() 
    const payload =  username: this.state.username, password: this.state.password  
    axios
      .post('login/', payload)
      .then(response => 
        const  token, user  = response.data;

        // We set the returned token as the default authorization header
        axios.defaults.headers.common.Authorization = `Token $token`;

        // Navigate to the home screen
        Actions.main();
      )
      .catch(error => 
            console.log(error)
      );

通过将令牌保存在我的标头中,它总是被发送。

【讨论】:

感谢您的建议!我刚试过这个,它似乎破坏了我的登录功能并导致它要求我登录两次?然后,一旦我有了我的令牌,我就会得到一个未经授权的 401。想法? 此编辑导致以下错误:代码 400,消息错误请求语法 ('"headers":"Authorization":"Bearer \\"TOKEN\\""OPTIONS /api /TestConnection/ HTTP/1.1') 其中 token 是 JWT 令牌【参考方案2】:

错误提示“来自原点'http://localhost:3000'”和“检查 cors 政策”

我看到你的 CORS 政策是

CORS_ORIGIN_WHITELIST = (
    'localhost:8000',
    'localhost:3000',
    'localhost'
)

也许可以尝试提供完整的 http url。所以

CORS_ORIGIN_WHITELIST = (
    'localhost:8000',
    'http://localhost:3000',
    'localhost'
)

【讨论】:

感谢您的想法,不幸的是它只是将错误更改为阻止localhost:3000 暂时摆脱白名单,看看是否可行。除了白名单之外,还允许全部打开有点矛盾 不幸的是,这也没有效果。【参考方案3】:

我解决了!解决方案非常简单(当然),

对于我需要使用@HenryM 解决方案的一部分的请求。

首先我需要建立默认网址:

axios.defaults.baseURL = 'http://127.0.0.1:8000/api/';

然后我将有效负载和标头保存到 const 变量中:

const header = 
  headers:
    'Authorization': "Bearer " + localStorage.getItem('JWTAccess')
  

const payload = 
  testValue: "Hello API"

最后,主要问题是我的参数顺序错误:

axios.post("TestConnection/", payload, header)
    .then(response => 
      console.log(response)
      )
    .catch(error => 
      console.log(error);

显然,至少在使用 Django Rest Framework 时,正确的顺序是有效载荷然后是标题!!!

感谢所有累了帮忙的人! 这是最终帮助我的文章:https://www.techiediaries.com/django-vuejs-api-views/

【讨论】:

以上是关于Django Rest Framework CORS 阻止 XMLHttpRequest的主要内容,如果未能解决你的问题,请参考以下文章

怎么安装django rest framework

django rest framework中文介绍

17-Django-Django REST framework-REST framework及RESTful简介

为啥 django-rest-framework 不显示 OneToOneField 数据 - django

Django:rest framework之分页(Pagination)

django使用rest_framework