React 应用程序未从 Express 服务器接收 res.data (JSON),尽管 Postman 确实如此
Posted
技术标签:
【中文标题】React 应用程序未从 Express 服务器接收 res.data (JSON),尽管 Postman 确实如此【英文标题】:React app not receiving res.data (JSON) from Express server although Postman does 【发布时间】:2019-10-08 12:11:04 【问题描述】:当通过 EC2 上的 PM2 向我们的 Express 服务器发送 POST 或 GET 请求时,Postman 会收到包括 JSON 数据在内的完整响应,但是我们的前端 React 应用程序(本地和通过 CF 部署的)只收到响应状态代码和消息,并将数据变量作为空白字符串。 React 应用正在使用 axios 进行这些调用。
我在 AWS 支持上花了很多时间,但我们得出的结论是 EC2 或 CF 没有问题。
我也和我的同事讨论了很多,我们认为这可能是一个异步问题,但我们被难住了。
这是客户端调用:
export function signIn (data)
return (dispatch) =>
dispatch(addSignInStatus('PENDING'))
axios.post(`$config.production_url/api/user/login`, data)
.then(res =>
return dispatch(addSignIn(res.data))
).catch(err =>
dispatch(addError(err))
return dispatch(addSignInStatus('ERROR'))
)
这是服务器端的响应:
export function login(req,res)
let username = ''
let password = ''
if(req.body.username && req.body.password)
username = req.body.username;
password = req.body.password;
else
res.status(400).json(
message:"Error logging In",
error: "No username or password specified"
);
return;
_user.login(username,password).then(data=>
res.status(200).json(data)
)
.catch(error=>
res.status(400).json(message:"Error Signing in User",error:error);
);
在 React 应用程序中,服务器以正确的状态代码和消息进行响应,但 res.data 作为空白字符串返回,并且在 Firefox 中抛出此错误:
SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data
服务器应该使用类似于以下内容的 JSON 对象进行响应:
"message": "Sign-in Successful",
"user":
"skills": [],
"social": [],
"wallets": [],
"followers": [],
"following": [],
"groupsOwned": [],
"groupsJoined": [],
"starred": [],
"pinned": [],
...
,
...
当请求通过邮递员发送时它会这样做。
编辑:
服务器确实接受跨源请求:
app.use(cors());
app.use(function(req, res, next)
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
);
编辑 2 解决方案:
原来是 npm 库“压缩”的问题
【问题讨论】:
【参考方案1】:看起来您正在发出失败的跨域请求。浏览器默认阻止跨域请求。跨域请求的概念不适用于 Postman,因为您的客户端(Postman)运行在您操作系统的所有网络权限下,而不是被限制在浏览器中。
在浏览器的开发者工具中检查您的“网络”标签。如果您的请求是跨域的,浏览器将在它们前面加上一个 OPTIONS 请求。这称为“预检请求”。
此时,如果您的服务器需要跨域流量,它应该使用一组授权跨浏览器请求的标头进行响应。如果是这样,浏览器将放心,没有人在做任何不正当的事情,它会继续发出您代码中的 POST 请求。
如果您的服务器不期望跨域流量,它不会响应这些标头。然后,浏览器将根据其安全模型阻止您在代码中编写的 POST 请求。它看起来像您描述的空白请求。
以下是在服务器上实施 CORS 所需了解的所有信息: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
【讨论】:
我忘了说服务器确实接受来自所有来源的请求:res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
这一切都正确吗?
据我了解,OPTIONS 请求中的 Access-Control-Allow-Headers 标头应该包含可能在 POST 请求中发送的标头的完整列表。所以在我的代码中我有res.setHeader("Access-Control-Allow-Headers", "Cache-Control")
。您可能需要查看浏览器随您的 POST 请求发送的所有标头并将它们添加到列表中。
我还有返回空白响应正文的代码(并跳过请求应该运行的其余代码)if (req.method === 'OPTIONS')
。我这样做是为了优化,还是因为它实际上是代码工作所必需的,我不记得了。
感谢所有帮助!原来是压缩的问题!我从server.js
中删除了该行,它就像一个魅力!以上是关于React 应用程序未从 Express 服务器接收 res.data (JSON),尽管 Postman 确实如此的主要内容,如果未能解决你的问题,请参考以下文章
请求正文未从 aws-serverless-express 模块进入 app.js 文件
react-icons/fa 安装失败:尝试导入错误:“FaStar”未从“react-icons/fa”导出
尝试导入错误:“useRouteMatch”未从“react-router-dom”导出
错误:./src/App.js 尝试导入错误:“Switch”未从“react-router-dom”导出