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

Mar*_*ian 21 apache reactjs webpack

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

这是我有的:

/var/www/index.html
/var/www/bundle.js
Run Code Online (Sandbox Code Playgroud)

我有

DocumentRoot /var/www
Run Code Online (Sandbox Code Playgroud)

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

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

<Link to="main"><button>Log In</button></Link>
Run Code Online (Sandbox Code Playgroud)

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

http://...com/main
Run Code Online (Sandbox Code Playgroud)

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

The requested URL /main was not found on this server
Run Code Online (Sandbox Code Playgroud)

我在React中的表述:

    <Router history={browserHistory }>
      <Route path="/" component={TopContainer}>
          <IndexRoute component={Login} />
          <Route path='main' component={MainContainer} />   
      </Route>
</Router>
Run Code Online (Sandbox Code Playgroud)

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

谢谢

Hin*_*ich 30

通过添加以下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>
Run Code Online (Sandbox Code Playgroud)

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

从这里感激地偷走了完整的答案

  • 为了进一步解释这是做什么的,如果`RewriteCond` 匹配(即文件或目录存在),那么`RewriteRule ^ - [L]` 表示“什么都不做”。否则,它会将任何其他流量重定向到 index.html。 (2认同)

Ali*_*man 10

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

Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [QSA,L]
Run Code Online (Sandbox Code Playgroud)


law*_*itt 8

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

  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>
Run Code Online (Sandbox Code Playgroud)
  1. sudo service apache2 restart

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


Mat*_*ava 7

上面的解决方案也适用于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>
Run Code Online (Sandbox Code Playgroud)

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


Fra*_*ack 6

好像这个链接(https://gkedge.gitbooks.io/react-router-in-the-real/content/apache.html)正是您需要的...

这部分配置对SPA有帮助:

这告诉Apache提供任何存在的文件,但是如果它们不存在,则仅提供/index.html而不是404:找不到

希望能解决您的问题!


VLR*_*enn 5

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

我的解决方案是观察请求期望接收的资源类型,因为浏览器在导航到页面时会要求 HTML(Firefox 要求text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8),而不是在初始加载后访问资源时(通过<script>ES6 模块导入的 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>
Run Code Online (Sandbox Code Playgroud)