gpt4 book ai didi

reactjs - 如何在驻留在使用从 React Router 构建的嵌套 URL 的子目录上的 SPA React 应用程序上正确配置 Apache?

转载 作者:行者123 更新时间:2023-12-05 01:35:44 25 4
gpt4 key购买 nike

我的网站托管在一个子目录中,例如 http://mywebsite/admin,其中/admin 是子目录

我已将我的 React 应用程序(create-react-app 生产构建)上传到/admin 子目录中。我还使用 react-router v4 BrowserRouter 来执行一些简单的客户端路由。以下是我的 react-app 中的一些相关片段:

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import { BrowserRouter } from 'react-router-dom';

import './css/custom.css';

ReactDOM.render(<BrowserRouter basename="/admin"><App /></BrowserRouter>, document.getElementById("root"));

在 App.jsx 渲染函数中

<Route
path='/students'
render={(props) =>
<Students
{...props}
/>
}
/>

<Route
path='/teachers'
render={(props) =>
<Teachers
{...props}
/>
}
/>

浏览网站时一切正常,工作正常,包括嵌套的 url,正如您在代码片段中看到的,主要是 /admin/students/admin/teachers.

主要问题:当我在 /admin/teachers 路径上并且我刷新页面时,页面没有加载任何内容.仅当我在 /admin 路线上时刷新才有效。但不是 /admin/teachers/admin/students

这不是我第一次使用托管在 Apache 服务器上的 react-router v4 构建 SPA。我重复使用了我之前项目中的 .htaccess。此 .htaccess 也位于 /admin 子目录中。下面是 .htaccess:

.htaccess

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.html?path=$1 [NC,L,QSA]

这会将所有请求路由到由 create-react-app 生产构建构建的 index.html。但是,根据我的调查,这种类型的配置仅适用于不在子目录中且未使用嵌套 URL 的项目。

请注意,我现在有 2 个 .htaccess。一个在根目录下,另一个在 /admin 子目录中。 两者都包含相同的 .htaccess 代码。这样做的原因是,我在根目录下运行了另一个 SPA。

我错过了什么?

如何在驻留在使用从 React Router 构建的嵌套 URL 的子目录中的 SPA React 应用程序上正确配置 Apache?

最佳答案

主要解决 OP's answer , 加上一些其他注释...

This is where I made a mistake:

Note, that I have 2 .htaccess now. One on root and another one at the/admin subdirectory. Both contain the same .htaccess codes. The reasonfor this is, I have another SPA running at the root directory.

这不一定是“错误”——您只需要确保使用了正确的指令即可。事实上,如果这两个 .htaccess 文件旨在成为完全独立的 SPA,则最好将它们分开。

要有两个独立的 - 相同的 - .htaccess 文件,要点是:

  • 使替换字符串相对,即。没有斜线前缀。
  • 不要包含 RewriteBase 指令。 (这将覆盖目录前缀。)

RewriteRule substitution 字符串是相对路径时,目录前缀(即 .htaccess 的位置 文件)在重写过程结束时添加回来。

因此,/.htaccess/admin/.htaccess 将包含相同的指令:

RewriteEngine on
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.+) index.html?path=$1 [L,QSA]

但是,此解决方案与 OP 的解决方案略有不同,即 URL 路径的 admin/ 部分未传递给 path URL 参数。如果需要,您可以对此进行硬编码。例如。 index.html?path=admin/$1。或者在您的脚本中说明这一点。

第一个 RewriteRule 只是一个小的优化,它在请求已经被重写为 index.html 之后阻止进一步的文件系统检查。

请注意,我将 (.*)(0 或更多)更改为 (.+)(1 或更多)。这避免了在请求根目录时进行额外的目录检查。 IE。 example.com/example.com/admin/。您没有重写这些请求,而是依赖于适当设置的 DirectoryIndex index.html - 这是服务器配置中的默认设置。

由于替换字符串(index.php?page=$1)是相对的,当在文档根目录中时,它会有效地重写为/index.php 并且在 /admin/.htaccess 中时,它将有效地重写回 /admin/index.php

请注意,/admin/.htaccess 中的 mod_rewrite 指令完全覆盖了父 .htaccess 文件中的 mod_rewrite 指令,因为 mod_rewrite 指令在默认情况下不被继承(不同于其他模块)。


或者,为了避免重复,同时仍然维护两个单独的 .htaccess 文件,您可以在 /admin/.htaccess 文件中启用 mod_rewrite 继承。例如……

在根 /.htaccess 文件中:

RewriteEngine on
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.+) index.html?path=$1 [L,QSA]

然后,在 /admin/.htaccess 中,您将拥有以下内容:

RewriteEngine On
RewriteOptions Inherit

继承父 mod_rewrite 指令,就好像它们被原地复制到 /admin/.htaccess 文件中一样。

但是,这增加了一层额外的复杂性。除了 /admin 中的 SPA 现在依赖于根 .htaccess 文件之外,您现在必须小心不要添加任何中断 指令到根 .htaccess 文件。


旁白:

RewriteCond %{REQUEST_URI} admin
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) admin/index.html?path=$1 [QSA,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.html?path=$1 [QSA,L]

在 URL 路径中检查“admin”的第一个条件(顺便说一下,这在 URL 路径中检查“admin”anywhere - 这不是严格正确的) - 可以在 RewriteRule 指令本身中更优化地执行检查。例如:

RewriteRule ^(admin/.*) admin/index.html?path=$1 [QSA,L]

如果需要,可以将这两条规则合二为一,但可能会牺牲一些清晰度。例如:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(admin/)?.* $1index.html?path=$0 [QSA,L]

$1 反向引用然后包含可选的路径前缀,admin/nothing$0 包含完整匹配项。

关于reactjs - 如何在驻留在使用从 React Router 构建的嵌套 URL 的子目录上的 SPA React 应用程序上正确配置 Apache?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62727936/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com