【问题标题】:create-react-app proxy request fails with 404 when backend is hosted on Azure当后端托管在 Azure 上时,create-react-app 代理请求失败并显示 404
【发布时间】:2018-09-09 22:17:25
【问题描述】:

我在设置我的 create-react-app 应用程序以将请求代理到我在 Microsoft azure 上的测试主机时遇到了一些问题。我在我的应用程序的 package.json 中设置了代理,如下所示:

"proxy":{
   "/api/*":{
   "target":"https://mytestbackend.azurewebsites.net",
   "secure":false
}
}

我已经设置了一个 axios 请求以发送到 azure 上的后端服务器。它位于一个独立的 .js 中,我从我的一个反应应用程序的事件中调用它。它看起来像这样:

import axios from 'axios';

const login = async (username, password) => {
   console.log("Username to send is:"+username);
   console.log("password to send is:"+password);
   let response = await axios.post('/api/user/login',  {username:username,password:password});
   console.log(response);
};

export {login};

问题不可能出在我的反应组件中,因为这两个 console.log() 调用表明正在接收输入的值。如果我从 package.json 中删除 "secure":false 设置,请求会失败并显示 Http 错误:500。但如果我使用安全设置,则会失败并显示 404 页面。有人可以解释一下我做错了什么吗?我只能在“localhost”上使用代理吗?文档另有说明。非常感谢任何帮助。

我已验证在 Azure 管理门户上运行开发服务器的域启用了 CORS。如果我直接使用后端的 URL(即不使用 create-react-app 代理)来执行请求,它就可以工作。问题一定出在代理的配置方式上。

不使用安全时发生的 HTTP Errpr 500 的响应文本是:

Proxy error: Could not proxy request /api/user/login from localhost:3000 to https://mytestbackend.azurewebsites.net (undefined).

附加信息:我还通过在我的开发机器上本地运行我的后端进行了测试。出现错误消息,但括号中的“未定义”显示“UNABLE_TO_VERIFY_LEAF_SIGNATURE”。如果使用"secure: false,我可以成功调用登录端点,但是调用其他需要认证的端点会失败,因为cookie不是由axios发送的。

做: curl -v https://mytestbackend.azurewebsites.net/api/user/login

有这个输出:

* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS alert, Server hello (2):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection #0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.

【问题讨论】:

  • FE也是部署在同一个服务器还是不同的服务器上?如果两台服务器不同,那么您是否打开了端口和IP进行通信?另外请让 500 错误发生并发布那里的异常详细信息
  • FE 在本地主机上运行(这是我的开发环境),但连接到托管在 azure 中的后端。我正在使用 create-react-app 的代理配置来转发请求。如果我使用硬编码的 URL 向后端发出前端请求,它就可以工作。我看到的问题是,当我执行 Ajax 请求时,Axios 没有发送我的 cookie。在后端和 Azure 门户上都启用了 CORS。我会尽快发布错误 500 详细信息。
  • 我已更新我的问题以包含异常的详细信息。
  • curl -v https://mytestbackend.azurewebsites.net/api/user/login的输出是什么
  • 我在问题中包含了 curl 的输出。

标签: reactjs azure create-react-app


【解决方案1】:

经过几天的尝试都没有成功,我终于找到了一个可行的设置。代理配置如下:

"proxy": {
"/api/user/login": {
  "target": "https://localhost:44396",
  "logLevel": "debug",
  "secure": false
},
"/api/secured/userinfo": {
  "target": "https://localhost:44396",
  "secure": false,
  "logLevel":"debug",
  "secure":false 
}

对客户端上两个端点的请求都有 withCredentials:true

 try {
    await axios({
        method:'post',
        url:'/api/user/login',
        withCredentials:true,
        data:
            {username:username,password:password}}
        );

    let userinfo =await axios.get('/api/secured/userinfo',{withCredentials:true});

   return userinfo;

如您所见,我已开始在本地开发机器上进行测试。无论出于何种原因,此设置都拒绝在 azure 托管的后端上运行。我本来希望它按我最初的预期工作,但至少现在我可以继续我的项目。

【讨论】:

  • 您可以尝试在代理对象中添加cookieDomainRewrite:"" 并尝试。使用secure:false,还可以查看changeOrigin: true 选项
【解决方案2】:

create-react-app 使用 WebPackDevServer 使用 https://github.com/chimurai/http-proxy-middleware#options

所以你可以使用相同的所有选项

现在在外部托管服务器的这种情况下导入的一个键headerhost。如果不正确,有时可能会出现问题,请参见下面的示例

Websocket works on EC2 url but not on ElasticBeanstalk URL

接下来是 cookie 可能与 localhost 相关联,我检查了它们应该没有任何修改。但您可能也想使用cookieDomainRewrite: "" 选项

所以我将使用的最终配置如下

"proxy":{
   "/api/*":{
   "target":"https://mytestbackend.azurewebsites.net",
   "secure":false,
      "headers": {
        "host": "mytestbackend.azurewebsites.net"
      },
      "cookieDomainRewrite": ""
  } 
}

您也想在您的客户端上使用withCredentials:true

let userinfo =await axios.get('/api/secured/userinfo',{withCredentials:true});

【讨论】:

  • 嗨,很抱歉,我知道问题的赏金已过期。从那以后,我决定不使用 React,而是使用 ASP.NET 的 Razor 进行服务器端渲染。不过,我仍然想让这个工作。这种配置对我也不起作用。 Cookie 仍未发送。并且对 /api/secured/userinfo 的请求失败。
  • 我终于设法让它工作了。我在 .env.development 中使用了您的配置以及设置 HTTPS=true。
  • 很高兴它对你有用。感谢您接受答案
  • 如果我使用 create react app,我必须在哪个文件中编写此配置?
  • @RAVIATEL,在你的package.json
【解决方案3】:

创建 react 应用 http-proxy-middleware,并且应该支持全套选项。

我会尝试的一些事情:

  • 如果你想嵌套多个层次,匹配的路径可能是/api/**而不是/api/*(例如/api/user/login

  • 如果您要远程代理(不在本地主机上),您可能需要添加 changeOrigin: true

  • 您可能希望保留 secure: false,因为您没有使用 https 运行 localhost

所以总的来说,我会尝试

"proxy":{
   "/api/**": {
     "target": "https://mytestbackend.azurewebsites.net",
     "secure": false,
     "changeOrigin": true
   }
}

【讨论】:

  • 尝试此操作后,我收到此错误消息: SyntaxError: Invalid regular expression: //api/**/: Nothing to repeat
猜你喜欢
  • 2018-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-07
  • 2020-08-04
  • 1970-01-01
相关资源
最近更新 更多