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”导出

尝试导入错误:“addLocaleData”未从“react-intl”导出

create-react-app + nodejs (express) 服务器