在预测试后由于CORS错误而无法使用React中的Axios发出http请求来表达。在服务器上启用了CORS,但仍无法正常运行

时间:2019-06-12 17:06:50

标签: reactjs express axios

我已经开发该应用程序已有几个月了,并且使用axios在开发和生产中都可以从React前端向Express后端发出http请求,而不会出现问题。昨天,我开始收到“ net :: ERR_EMPTY_RESPONSE”消息,检查网络呼叫后,我意识到这是因为它正在执行飞行前OPTIONS请求,然后没有再进行后续的实际请求。

我包括了cors express模块​​,并将其放在服务器上我的路由上方。我专门为所有OPTIONS请求创建了中间件,该中间件将设置其“ Access-Control-”标头以允许所有来源,方法和标头(是的,我知道这是一个漏洞)。在我的react应用程序中,我在package.json中设置了“ proxy”:“ https://example.com”。即使完成所有这些操作,我仍然无法使我的React应用程序(或浏览器?)与任何“复杂的”请求配合使用(我的理解是,任何带有Authorization标头的内容都将触发预检)。我一直在成功地从开发(localhost:3000)和具有相同来源(https://example.com)的生产应用程序访问这些受保护的路由,直到昨天。我看到很多其他人对此有疑问,但是他们中的任何一个都无法从生产向自己的服务器发出网络请求。

   //package.json for React app
   "name": "homebrew",
  "version": "0.1.0",
  "private": true,
  "proxy": "https://example.com",
  "dependencies": {
    "axios": "^0.19.0",
    "gsap": "^2.1.2",
    "jwt-decode": "^2.2.0",
    "react": "^16.8.5",
    "react-dom": "^16.8.5",
    "react-helmet": "^5.2.1",
    "react-router-dom": "^5.0.0",
    "react-scripts": "2.1.8",
    "request": "^2.88.0"
  },
 //Admin component in React App
 componentDidMount(){
        var jwt = JSON.parse(localStorage.getItem('brew-jwt'));

        let config =
        { headers : {
              'Authorization': "Bearer " + jwt,
            }
        }

        console.log(jwt);
        axios.get('https://example.com/admin/submissions',config)
        .then(response =>{
            console.log(response);
        })
        .catch(error=>{
            console.log(error);
        })

   }
  //server.js file
  var port = 443;
  var app = express();



  app.use(cors());

  app.set('views', path.join(__dirname,'views'));
  app.set('view engine', 'ejs');
  app.engine('html', require('ejs').renderFile);
    //Farther down in my server.js file
    app.options('*',function(req,res){
       res.header('Access-Control-Allow-Origin', '*');
       res.header('Access-Control-Allow-Methods', 'GET,PUT,HEAD,POST,PATCH');
       res.header('Access-Control-Allow-Headers', 
       'Authorization,Origin,Referer,Content-Type,Accept,User-Agent');
        res.sendStatus(200);
        res.end();
     });

     app.use('/',index);
     app.use('/users',users);
     app.use('/forgot',forgot);
     app.use('/ingredients',ingredients);
     app.use('/admin',admin);
     app.use('*',index);





The OPTIONS request sends this request to my server:

Access-Control-Request-Headers: authorization,content-type
Access-Control-Request-Method: POST
Origin: http://localhost:3000
Referer: http://localhost:3000/Admin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36


The OPTIONS request gets this response from my server:

Request URL: https://example.com/admin/submissions
Request Method: OPTIONS
Status Code: 204 No Content

Access-Control-Allow-Headers: authorization,content-type
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Origin: *

The headers my actual request were to send are:
 Accept,Auhtorization,Content-Type,Origin,Referer,User-Agent
This request is never being sent, though, because I am logging requests on my server and it never receives it. 

Note: I am able to make "simple" network requests from my front-end still, like fetching public resources, images, etc. 

Is this a chrome problem? A react problem? Axios problem? Help!

1 个答案:

答案 0 :(得分:0)

解决了。问题是我在Authorization标头中发送的jwt(json网络令牌)太大,原因是它包含除用户凭据之外的其他用户数据(实际上是很多数据)。当我不小心从本地存储中删除令牌并仍然尝试请求时,我发现了这一点。它设法发送了Authorization标头,但其内容只是'Bearer null'。我再次登录以接收令牌并重新尝试,这给了我CORS外观问题。毕竟不是问题。我的请求标头太大!

解决方案是在用户登录时向其发送2个令牌;较小的用户jwt将作为授权标头发送回服务器,而较大的用户数据jwt将保存所有用户保存的数据。当jwt太大而无法作为标头发送时,它会导致出现CORS /印前检查问题,但实际上,未发出请求的唯一原因是较大的标头。很多人可能都遇到了这个问题,却没有意识到(我到处都看到了对此失去理智的人)。