我已经开发该应用程序已有几个月了,并且使用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!
答案 0 :(得分:0)
解决了。问题是我在Authorization标头中发送的jwt(json网络令牌)太大,原因是它包含除用户凭据之外的其他用户数据(实际上是很多数据)。当我不小心从本地存储中删除令牌并仍然尝试请求时,我发现了这一点。它设法发送了Authorization标头,但其内容只是'Bearer null'。我再次登录以接收令牌并重新尝试,这给了我CORS外观问题。毕竟不是问题。我的请求标头太大!
解决方案是在用户登录时向其发送2个令牌;较小的用户jwt将作为授权标头发送回服务器,而较大的用户数据jwt将保存所有用户保存的数据。当jwt太大而无法作为标头发送时,它会导致出现CORS /印前检查问题,但实际上,未发出请求的唯一原因是较大的标头。很多人可能都遇到了这个问题,却没有意识到(我到处都看到了对此失去理智的人)。