如何使 React 路由器和 nodejs/express 路由在 cpanel/shared 托管中协同工作?

How to make react router and nodejs/express routes work together in cpanel/shared hosting?

我有一个部署在共享 hosting/cpanel 上的 MERN 应用程序。现在我的服务器端工作了,但是当我尝试访问一个页面时,反应路线没有,例如。 domain.com/about ,它在我的服务器上用作获取请求,而不是转到关于页面。我使用 npm 运行 构建,并将构建文件夹中的所有文件上传到 public_html。然后我将服务器端的存储库(客户端和服务器具有不同的存储库)克隆到 home/username/server.

原来这是我的文件结构

client
    -src
    -package.json
    -etc
    -build (after npm run build)
server
    -app.js
    -models
    -routes
    -events
    -packagejson
    -etc

然后我在 cpanel 上创建了一个 nodejs 应用程序。 这就是我放在我的节点 js 应用程序上的内容。

Application Mode : Product
Application Root : server
Application URL : domain.com
Application Startup file : app.js

现在我的文件管理器上看起来像这样

/home/username
    -public_html
         -index.html
         -other files from build folder
    -server
         -app.js
         -etc

现在我尝试将此 apache 配置添加到现有的 .htaccess 配置(其中包含 nodejs 的 passport 配置)

RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . /index.html [L]

有了它,我的反应路由器可以工作,但我的服务器没有。如何让服务器路由和反应路由同时工作?对不起,我是新来的。谢谢!

我假设您将前端应用程序路由配置为使用浏览器的历史记录 API,因此您将拥有“不错的”URLs(没有散列、感叹号等)。

您的问题来自于这样一个事实,即现在您有两个应用程序在竞争路由解析。一个在前端(在您的情况下是 React 应用程序),一个在后端(Web 服务器,通常是 Apache)。您的后端服务器需要知道什么时候应该发送到客户端前端应用程序,这是从 index.html 文件引导的。因此,当用户刷新页面时(例如通过在键盘上按 F5),服务器将识别出所请求的 URL 属于前端应用程序并将发送此 index.html 文件。

您有两个选项可以让它发挥作用:

  1. 在 React 应用程序中,从历史 API“干净”URLs 切换到“hashbang”风格 URLs,所以你的 link将用于前。 domain.com/#!/about 而不是 domain.com/about – 此解决方案不需要对后端配置进行任何更改,而且很简单(之所以可行,是因为 # 之后的所有内容都在浏览器本地解析)。

  2. 让后端服务器知道哪些路由属于前端应用程序,并在匹配时始终以 index.html 响应——这需要正确的 Web 服务器路由配置和规则分辨率,如果发生冲突,将使用前端路由“覆盖”或“隐藏”任何后端路由(或文件)。您尝试这样做,但是它使您的后端路由的其余部分无法使用。有变通办法——例如:you could put your app in a subdirectory,使配置更容易;或者你可以在 htaccess 中包含所有的前端路由;或者你可以捕获 404 错误然后发送 index.html,然后在你的 React 应用程序中仍然找不到特定路由之后,然后显示 404 页面。如果你不知道自己在做什么,那么我建议坚持第一个解决方案。

更多信息:

我通过在我的应用程序 url 中添加 /api 解决了这个问题。 我的节点 js 应用程序如下所示:

Application URL : domain.com/api

然后我刚刚在我的路线上添加了 /api