【问题标题】:How to setup apache server for React route?如何为 React 路由设置 apache 服务器?
【发布时间】:2017-10-17 17:15:33
【问题描述】:

我的 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 配置中还缺少什么?

谢谢

【问题讨论】:

  • 你应该选择一个正确的答案。感谢您的提问。

标签: apache reactjs webpack


【解决方案1】:

通过添加以下 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

感谢从here盗取的完整答案

【讨论】:

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

上述解决方案也适用于 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>

&lt;VirtualHost ...&gt;下的上述文件

【讨论】:

  • 谢谢这个帮了我很多,节省了我的时间。
  • 对于谷歌员工,&lt;Directory "/var/www/html"&gt;&lt;/Directory&gt; 是使其正常工作所必需的。
  • 在使用 .htaccess 文件之前,我们需要更新 AllowOverride 设置以便能够覆盖 Apache 指令。编辑文件/etc/httpd/conf/httpd.conf 找到&lt;Directory /var/www/html&gt; 部分并将AllowOverride 指令从None 更改为All
  • 我将您的解决方案与@VLRoyrenn 的答案结合起来,它在 Ubuntu 上对我有用。
  • 非常感谢。
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    什么对我有用,在这里呼应了许多答案和 cmets:

    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 文件中没有像之前的答案所建议的那样工作。

    【讨论】:

      【解决方案5】:

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

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

      编辑: MDN has a list of common values 用于 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>
      

      【讨论】:

      • 我将您的解决方案与@MatusDubrava 的答案结合起来,它在 Ubuntu 上对我有用。
      • 将前 5 行(RewriteEngine、RewriteConds 和 RewriteRules)添加到我的应用程序 html_public 文件夹的 .htaccess 中,这就足够了。
      【解决方案6】:

      谢谢!这对我有用。

      如果您服务于多个站点(虚拟主机)以及 SSL 证书(SSL 是使用 certbot 制作的),我将粘贴我的配置,并将 http 重定向到 https

      此设置适用于 Linode / Ubuntu

      yoursite.com-le-ssl.conf

      <IfModule mod_ssl.c>
      <VirtualHost *:443>
        # Admin email, Server Name (domain name), and any aliases
        ServerAdmin webmaster@yoursite.com
        ServerName  yoursite.com
        ServerAlias www.yoursite.com
      
        # Index file and Document Root (where the public files are located)
       DirectoryIndex index.html index.php
        DocumentRoot /var/www/html/yoursite.com/public_html 
      <Directory  "/var/www/html/yoursite.com/public_html">
          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>
        # Log file locations
        LogLevel warn
        ErrorLog  /var/www/html/yoursite.com/log/error.log
        CustomLog /var/www/html/yoursite.com/log/access.log combined
      Include /etc/letsencrypt/options-ssl-apache.conf
      SSLCertificateFile /etc/letsencrypt/live/yoursite.com/fullchain.pem
      SSLCertificateKeyFile /etc/letsencrypt/live/yoursite.com/privkey.pem
      </VirtualHost>
      </IfModule>
      

      【讨论】:

        【解决方案7】:

        在 ubantu 服务器上修复了 React 路由问题

        解决方案:

        1. 使用控制台打开文件。

        如果您使用 SSL 纳米 /etc/apache2/sites-available/000-default-le-ssl.conf

        添加以下行

        ================================================ ======================================

        DocumentRoot /var/www/project 重写引擎开启 RewriteCond %{HTTP_ACCEPT} 文本/html RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.html [最后] RewriteRule ^ - [最后一个]

        AllowOverride None
        Options FollowSymLinks Multiviews 
        Require all granted
        

        【讨论】:

          【解决方案8】:

          进入这个目录

          1. /etc/apache2/sites-available

          2. 打开文件:000-default.conf

          3. 更改权限:777

          4. 在文件底部粘贴代码

          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] 
          

          1. 重启服务器

          【讨论】:

          • 将权限更改为 777 并不是一个好建议,即使它可以让部署工作。
          • 投反对票,因为它建议将文件权限更改为 777
          猜你喜欢
          • 2014-04-21
          • 2017-09-02
          • 2018-03-13
          • 1970-01-01
          • 2023-03-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多