如何为 React 路由设置 apache 服务器?

IT技术 apache reactjs webpack
2021-03-23 08:54:46

我的 React 应用程序在本地开发服务器上运行良好,但是当我将生产就绪文件直接转储到 Apache 的 htdocs 目录时它不起作用:

这是我所拥有的:

/var/www/index.html
/var/www/bundle.js

我有

DocumentRoot /var/www

在 /etc/apache2/sites-available/000-default.conf

事实是
1)。当我访问http://...com/ 时,将我路由到登录页面
2)。在我点击链接之后

<Link to="main"><button>Log In</button></Link>

浏览器位置字段中的内容变为:

http://...com/main

3)。现在,如果我重新加载这个 url ( http://...com/main ),我得到了

The requested URL /main was not found on this server

我在 React 中的循环:

    <Router history={browserHistory }>
      <Route path="/" component={TopContainer}>
          <IndexRoute component={Login} />
          <Route path='main' component={MainContainer} />   
      </Route>
</Router>

我在 apache 配置中还缺少什么?

谢谢

6个回答

通过添加以下 Rewrite* 行来更改VirtualHost 配置(通常在 中找到/etc/httpd/conf.d\vhosts.conf):

<VirtualHost *:8080>
  ServerName example.com
  DocumentRoot /var/www/httpd/example.com

  <Directory "/var/www/httpd/example.com">
    ...

    RewriteEngine on
    # Don't rewrite files or directories
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    # Rewrite everything else to index.html to allow html5 state links
    RewriteRule ^ index.html [L]
  </Directory>
</VirtualHost>

这告诉 Apache 提供任何存在的文件,但如果它们不存在,则只提供服务/index.html而不是404: not found.

完整的答案从这里窃取

如果我只想重写目录但在文件上有 404,那么这条规则会怎样?
2021-05-31 08:54:46
为了进一步解释这是做什么的,如果RewriteCond匹配(即文件或目录存在),则RewriteRule ^ - [L]表示“什么都不做”。否则,它会将任何其他流量重定向到 index.html。
2021-06-06 08:54:46
谢谢@Hinrich,这个解决方案在 ubuntu 20.04 中适用于 react 16.13.0 和 react-router-dom 5.1.2。
2021-06-15 08:54:46

上述解决方案也适用于Ubuntu,但我在使用它时遇到了一些困难,因此这里是使其工作所需的步骤。

您需要放置上述配置的文件的位置在

/etc/apache2/sites-enabled

默认是

/etc/apache2/sites-enabled/000-default.conf

然后你需要确保 RewriteEngine 正在运行(否则你会在重新启动 Apache 服务器时出现错误)。

sudo a2enmod rewrite

最后重启Apache服务器

sudo /etc/init.d/apache2 restart

现在,它应该可以工作了。

当您使用默认配置时(网站的根目录在 下/var/www/html),那么您需要做的就是放置

<Directory "/var/www/html">
    RewriteEngine on
    # Don't rewrite files or directories
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    # Rewrite everything else to index.html to allow html5 state links
    RewriteRule ^ index.html [L]
</Directory>

到上述文件下 <VirtualHost ...>

感谢这个帮助我很多并节省我的时间。
2021-06-01 08:54:46
对于谷歌人来说,<Directory "/var/www/html"></Directory>是使其工作所必需的。
2021-06-09 08:54:46
非常感谢。
2021-06-09 08:54:46
在使用 .htaccess 文件之前,我们需要更新AllowOverride设置以便能够覆盖 Apache 指令。编辑文件/etc/httpd/conf/httpd.conf找到该<Directory /var/www/html>部分并将AllowOverride指令从更改NoneAll
2021-06-13 08:54:46
我将您的解决方案与@VLRoyrenn 的答案结合起来,它在 Ubuntu 上对我有用。
2021-06-15 08:54:46

如果您必须使用 .htaccess 和一个子目录,那么以下对我有用。

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]

什么对我有用,与这里的许多答案和评论相呼应:

  1. sudo a2enmod rewrite
  2. 打开 /etc/apache2/apache2.conf
  3. 粘贴到你的根路径:
<Directory "/var/www/PATH_TO_YOUR_ROOT">
    RewriteEngine on
    # Don't rewrite files or directories
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    # Rewrite everything else to index.html to allow html5 state links
    RewriteRule ^ index.html [L]
</Directory>
  1. sudo service apache2 restart

粘贴到特定于站点的 conf 文件并没有像之前的答案所建议的那样工作。

到目前为止发布的解决方案似乎都没有解决丢失资源错误地返回 200 而不是 404 的问题,这可能会使某些文件丢失时的调试变得相当烦人。

我的解决方案是观察请求期望接收的资源类型,因为浏览器在导航到页面时会要求 HTML(Firefox 要求text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8),而不是在初始加载后访问资源时(通过<script>ES6 module导入的 JS 文件)请求*/*,CSS 文件请求text/css,*/*;q=0.1,通过fetch()API访问 JSON将指定application/json, text/plain, */*等等)。通过依赖该假设,当尝试访问不存在的文件(例如仅在单页应用程序中有效的路由)时,可以将 Apache 配置为为单页应用程序提供服务,而无需在 SPA 请求访问时发送它已重命名的 CSS 文件或丢失的 JSON 文件。

编辑: MDN 有一个Accept 标头的通用值列表

<Directory  "/var/www/httpd/example.com">
    RewriteEngine on

    # Browsers will specifically ask for HTML (among other things) on initial page load
    # That is, if the *user* tries to access a *nonexisting* URL, the app is loaded instead
    # but if a webpage attempts to load a missing resource it will return 404.
    # (You can still go to /myreactapp/favicon.ico, but a missing /myreactapp/favicon.png resource won't return 200)

    # if (HTTP_ACCESS.contains('text/html') && file_not_exists(REQUEST_FILENAME))
    RewriteCond %{HTTP_ACCEPT} text/html
    RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^ index.html [last]

    # Any ressources loaded by index.html should behave correctly (i.e: Return 404 if missing)
    RewriteRule ^ - [last]

    AllowOverride None
    Options FollowSymLinks Multiviews 
    Require all granted
</Directory>
将前 5 行(RewriteEngine、RewriteConds 和 RewriteRules)添加到我的应用程序的 html_public 文件夹上的 .htaccess 中,这就足够了。
2021-06-11 08:54:46
我将您的解决方案与@MatusDubrava 的答案结合起来,它在 Ubuntu 上对我有用。
2021-06-12 08:54:46