来自React的HTTP请求未到达生产服务器上的Express后端

时间:2019-10-26 00:40:10

标签: node.js reactjs express http cpanel

我有一个React前端(由create-react-app制造)和一个Express后端,以及一个远程MySQL数据库。当我同时在本地运行,在localhost:3000上服务前端并将http请求代理到localhost:3306时,一切工作正常,这也是Express应用程序侦听的端口。向localhost:3000/api/endpoint发出了请求,同样有效。

我现在正在尝试将此设置移至服务器上的生产环境。我正在使用共享服务器,并且通过Cpanel配置了Node(尽管我确实具有SSH访问权限)。我没有像开发中那样在服务器上“运行” React端,而是创建了构建文件并将其放置在与我的域主页相对应的目录中。

比方说我的域名是foo.com。我的托管公司建议我在端口50000上运行Node(因为当我尝试使用3306时,它说它已经在使用)。当前,对我的API的每个请求似乎都导致404:它试图查询foo.com/api/endpoint并失败。我的问题是:如何正确地将这些请求定向到后端?我知道React package.json中的proxy选项并不是真的要在生产中使用,因此我应该使用什么,应该将其设置为什么?我还应该在服务器上配置什么?


更新

好吧,我现在正试图绕过Cpanel的节点管理器并手动运行。我在服务器上的文档结构如下:

/home/user
|--- /project
|   |--- /backend
|       |--- (Node server.js, etc.)
|   |--- /client
|       |--- (React src, components, etc.)
|--- /public_html
    |--- (React build files)
    |--- .htaccess

我相信React构建文件必须位于public_html中,服务器才能在我的主页上呈现它们。因此,我目前从后端提供构建文件(尽管@MattCarlotta建议我在下面进行此操作;如果有必要,我愿意这样做。React应用本身似乎正在运行可以在3ecologies-seedbank.com上直播;但是也许我还需要告诉节点服务器public_html的位置?)。

其他资源使我认为答案的一部分在于.htaccess文件。我的当前看起来像这样(包括一些由Cpanel生成的代码):

# php -- BEGIN cPanel-generated handler, do not edit
# Set the “ea-php56” package as the default “PHP” programming language.
<IfModule mime_module>
  AddHandler application/x-httpd-ea-php56 .php .php5 .phtml
</IfModule>
# php -- END cPanel-generated handler, do not edit

RewriteEngine On
RewriteRule ^/public_html$ http://127.0.0.1:50000/ [P,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/public_html/(.*)$ http://127.0.0.1:50000/$1 [P,L]

我对此的粗略理解是将请求从public_html的页面重定向到我的Node应用程序,该应用程序正在端口50000上侦听。这对我来说很有意义,因为当我在本地同时运行back和front时,我需要将请求从localhost:3000(前面)代理到localhost:3306(后面)。

我已经使用简单的node server.js通过SSH启动了Node应用程序。能够确认它正在侦听端口50000并连接到数据库。但是,从前端对API的每个请求仍然会导致404。似乎仍未达到后端。

如果有帮助,我正在与Apache 2.4.41和Cpanel 82.0(内部版本17)共享的服务器上。


TL; DR 在React中设置proxy以便将请求发送到Node后端的效果相当于什么?

1 个答案:

答案 0 :(得分:1)

好的,您遇到了一些困扰您的问题:

  • 您正在使用仅在开发中有效的package.json代理。而是在客户端使用axios configuration在API方面使用cors configuration,以允许两者在开发/生产中进行通信。

  • 您的server.js没有为您的客户build生产资产提供服务,因此我提供了example的服务方法。另外,我在无政府档案管理员的package.json中添加了production脚本,以创建一个有效的本地生产示例。只需键入npm run productionyarn production即可运行示例。在这个简单的示例中,转到localhost:5000,客户端将立即尝试通过调用发现的IFFE here来验证伪造的JWT令牌。该API将接收令牌,对其进行身份验证,然后以“无效令牌”警报进行响应。

  • 我无法使您的API路由配置正常工作,因此我建议采用更标准的方法。

例如:

const authRoutes = require("./routes/api/auth");

app.use("/api/auth", authRoutes);

app.use("/api/auth", require("./routes/api/auth"));

执行上述操作可以使您正常运行。

这是一个工作仓库https://github.com/mattcarlotta/seedbank-example


其他一些注释...

您可以使用async/awaittry/catch块来简化许多API控制器代码。例如,this(如果标头不包含授权,当前会导致应用崩溃)可以简化为this(不幸的是,JWT使用回调而不是promises,所以我将其包装在保证清洁度-但要点是verify控制器更易于阅读,可以捕获任何错误并将其发送回客户端,而不会使您的应用程序崩溃。