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

时间:2017-05-18 04:12:59

标签: apache reactjs webpack

我的反应应用程序在我的本地开发服务器上运行良好,但是当我将生产就绪文件直接转储到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)。现在如果我重新加载这个网址(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配置中还缺少什么?

感谢

9 个答案:

答案 0 :(得分:20)

通过添加以下重写*行来更改 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

感激地偷走了完整答案

答案 1 :(得分:6)

似乎这样的链接(https://gkedge.gitbooks.io/react-router-in-the-real/content/apache.html)正是您所需要的......

这条配置对SPA有帮助:

  

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

希望能解决你的问题!

答案 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>

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

答案 3 :(得分:2)

到目前为止,尚未发布任何解决方案来解决丢失资源错误地返回200而不是404的问题,当某些文件丢失时,这会使调试变得很烦人。

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

<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>

答案 4 :(得分:2)

什么对我有用,在这里回荡了许多答案和评论:

  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 :(得分:2)

谢谢!这对我有用。

如果您要同时服务多个站点(虚拟主机)和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>

答案 6 :(得分:1)

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

Appearance & Behavior | System Settings | Project Opening

答案 7 :(得分:0)

在Ubuntu服务器上解决的路由问题

解决方案:

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

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

添加以下几行

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

DocumentRoot / var / www / project <目录“ / var / www / project”> 在RewriteEngine上 RewriteCond%{HTTP_ACCEPT} text / html RewriteCond%{REQUEST_FILENAME}!-f RewriteRule ^ index.html [最后] RewriteRule ^-[last]

AllowOverride None
Options FollowSymLinks Multiviews 
Require all granted

答案 8 :(得分:-1)

转到该目录

  1. / etc / apache2 / sites-available

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

  3. 更改其权限:777

  4. 在文件底部粘贴代码

import javax.swing.*; 
import java.awt.*; 
import java.text.*; 
import java.time.DayOfWeek; 
import java.time.LocalDateTime; 
import java.time.Month; 
import java.util.*;

public class Newdate implements Runnable {
    JFrame f;
    Thread t1 = null;
    int hours = 0, minutes = 0, seconds = 0;
    String timeString = "";
    JButton b;

    public void DigitalWatch() {
        f = new JFrame();

        t1 = new Thread(this);
        t1.start();

        b = new JButton();
        b.setBounds(50, 120, 200, 50);

        f.add(b);
        f.setSize(300, 400);
        f.setLayout(null);
        f.setVisible(true);
    }

    public void run() {
        try {
            while (true) {

                LocalDateTime currentTime = LocalDateTime.now();
                Month month = currentTime.getMonth();
                int day = currentTime.getDayOfMonth();
                int year = currentTime.getYear();
                DayOfWeek dayOfWeek = currentTime.getDayOfWeek();

                Calendar cal = Calendar.getInstance();
                hours = cal.get(Calendar.HOUR_OF_DAY);
                if (hours > 12)
                    hours -= 12;
                minutes = cal.get(Calendar.MINUTE);
                seconds = cal.get(Calendar.SECOND);

                SimpleDateFormat formatter = new SimpleDateFormat("dd-MMMM-yyyy HH:mm:ss");
                Date date = cal.getTime();
                timeString = formatter.format(date);

                printTime();

                t1.sleep(10); // interval given in milliseconds
            }
        } catch (Exception e) {
        }
    }

    public void printTime() {
        b.setText(timeString);
    }

    public static void main(String[] args) {
        Newdate dt = new Newdate();
        dt.DigitalWatch();

    }
}

  1. 重新启动服务器