我有一个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
中,服务器才能在我的主页上呈现它们。因此,我目前正在[[NOT从后端提供构建文件(尽管@MattCarlotta建议我在下面进行此操作;如有必要,我愿意这样做。React应用本身似乎可以在ok上实时运行) 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]
我对此的粗略理解是将请求从在React中将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
proxy
设置为将请求发送到Node后端的产量等同于什么?package.json
代理。而是在客户端使用axios
configuration在API方面使用cors configuration,以允许两者在开发/生产中进行通信。 server.js
没有为您的客户build
生产资产提供服务,因此我提供了如何进行此服务的example。另外,我在无存档的production
中添加了package.json脚本,以创建一个有效的本地生产示例。只需键入npm run production
或yarn production
即可运行示例。在此简单示例中,转到localhost:5000,客户端将立即尝试通过调用找到的IFFE来验证伪造的JWT令牌。 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/await
块来简化许多API控制器代码。例如,try/catch
(如果标头不包含授权,当前会导致您的应用崩溃)可以简化为this(不幸的是,JWT使用回调而不是Promise,因此我将其包装在Promise中是为了保持整洁-但主要要点是this控制器更易于阅读并捕获任何错误,然后将它们发送回客户端,而不是使您的应用程序崩溃。]