【问题标题】:React + Django Axios IssuesReact + Django Axios 问题
【发布时间】:2019-05-11 23:18:27
【问题描述】:

我有一个反应应用程序链接到两个独立服务器上的 Django 后端。我正在为 django 使用 DRF,并且我允许使用 django-cors-headers 的 cors。出于某种原因,当我 curl POST 后端时,我能够发出请求。但是,当我使用 axios POST 后端时,我得到了错误。来自 axios 的 POST 请求状态为 failed。该请求需要 10 多秒才能完成。我的代码在本地工作(react 和 django 代码),但是当我部署到 AWS ec2 ubuntu 时,axios 请求停止工作。

控制台错误日志

OPTIONS http://10.0.3.98:8000/token-auth/ net::ERR_CONNECTION_TIMED_OUT
{
  "config": {
    "transformRequest": {},
    "transformResponse": {},
    "timeout": 0,
    "xsrfCookieName": "XSRF-TOKEN",
    "xsrfHeaderName": "X-XSRF-TOKEN",
    "maxContentLength": -1,
    "headers": {
      "Accept": "application/json, text/plain, */*",
      "Content-Type": "application/json;charset=UTF-8",
      "Access-Control-Allow-Origin": "*"
    },
    "method": "post",
    "url": "http://10.0.3.98:8000/token-auth/",
    "data": "{\"username\":\"testaccount\",\"password\":\"testpassword\"}"
  },
  "request": {}
}

这是我的请求代码

axios.post('http://10.0.3.98:8000/token-auth/',
                JSON.stringify(data),
                {
                    mode: 'no-cors',
                    headers: {
                        'Content-Type': 'application/json',
                        'Access-Control-Allow-Origin' : '*'
                    },
                 },
            ).then( res => (
                console.log(JSON.stringify(res)),

            )
            ).catch( err => (
                console.log(JSON.stringify(err))
                )
            );

我的 curl 代码有效

curl -d '{"username":"testaccount", "password":"testpassword"}' -H "Content-Type: application/json" -X POST http://10.0.3.98:8000/token-auth/

更新 1

在 Firefox 上我收到警告

跨域请求被阻止:同源策略不允许读取 http://10.0.3.98:8000/token-auth/ 的远程资源。 (原因: CORS 请求未成功)。[了解详情]

更新 2

也许这与我的 AWS VPC 和子网有关?我的 django 服务器位于私有子网中,而我的 react 应用位于公共子网中。

更新 3 - 我对问题的看法

我认为我来自 axios 的请求不起作用的原因是因为我发出的请求是将请求标头的来源设置为 http://18.207.204.70:3000 - 公共/外部 IP 地址 - 而不是私有/内部ip 地址是http://10.0.2.219:3000 - 我在网上搜索来源是一个禁止字段,所以它不能更改。那我该如何设置原点?我必须使用代理吗?我该怎么做。

【问题讨论】:

  • 你用 fetch() 试过了吗?有些 axios 函数不能用 xhtmlrequest 作为包装器进行 1:1 转换
  • 是的 - 我只是尝试了同样的错误,除了选项标头没有首先发送 POST 10.0.3.98:8000/token-auth net::ERR_CONNECTION_TIMED_OUT
  • 您需要让您的应用程序服务器响应预检OPTIONS 请求,并使用响应标头指定允许哪些主机来源向应用程序服务器请求。为响应预检请求而必须设置回的响应标头是 Access-Control-Allow-Origin
  • 我也试过了,我会用我使用的标题更新我的问题
  • 哦,http://10.0.3.98:8000/ 的应用程序服务器必须更新以响应来自运行脚本的主机的预检请求。我的意思不是在axios 客户端中设置请求标头。

标签: django reactjs axios


【解决方案1】:

试试这个 http 请求而不是 axios,它叫做 superagent (https://www.npmjs.com/package/superagent),只需通过 npm 将它安装到你的 react 应用程序中,

npm i superagent

并使用它来代替 axios。

import request from 'superagent'

    const payload ={
                    "1": this.state.number,
                    "2": this.state.message
                    }


    request.post('LINK HERE')
            .set('Content-Type', 'application/x-www-form-urlencoded')
            .send(payload)
            .end(function(err, res){
                if (res.text==='success'){
                    this.setState({
                        msgAlert: 'Message Sent!',
                    })
                }
                else{
                    console.log('message failed/error')
                }
            }); 

【讨论】:

  • 错误:请求已被终止可能原因:网络离线、Access-Control-Allow-Origin不允许Origin、正在卸载页面等
  • 我认为这与 reactjs 或我的包有关。当我编写一个尝试使用 axios、fetch 或 superagent 的节点脚本时——它们都可以工作。当我将代码放入 react 项目时,它们不再起作用。
  • 通常浏览器会发出预检请求,以验证是否允许运行脚本的主机在另一台主机上执行请求。这仅允许应用服务器验证的主机向应用程序发出浏览器请求。
【解决方案2】:

这里的问题是在客户端浏览器上发出请求。您需要使用反向代理或直接向 api 服务器请求。您也不能进行本地 ssh 转发。

【讨论】:

    猜你喜欢
    • 2021-05-20
    • 2018-09-03
    • 2020-02-12
    • 2021-05-30
    • 1970-01-01
    • 1970-01-01
    • 2022-11-08
    • 2019-05-31
    • 1970-01-01
    相关资源
    最近更新 更多