htaccess:将路径参数国家/地区代码添加到URL并投放index.html

问题描述

我想通过htaccess将国家代码'en-gb'添加到Angular应用程序中。文件夹“ en-gb”不存在。我只希望它显示在url中并投放index.html

我的.htaccess

<IfModule mod_rewrite.c>
    RewriteEngine On
   
    #does the folder AND file exist? (ie. /index.html & css/style.css)
    #yes - serve it & pop out of htaccess
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
    RewriteRule ^ - [L]

    #does the url already have a country flag set?
    #no - add country flag (ie. http://angular.wlocal/ -> http://angular.wlocal/en-gb)
    RewriteCond %{REQUEST_URI} !/en-gb
    RewriteRule ^(.*)$ en-gb/$1
    
    #if file folder not found,serve index.html (ie. http://angular.wlocal/en-gb/this-does-not-exist -> should serve index.html)
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . index.html [L]

</IfModule>

我的虚拟主机

<VirtualHost 192.168.56.1:80>
    DocumentRoot "C:\Users\Dev\Documents\angular-10\dist"
    ServerName angular.wlocal
    ServerAlias angular.wlocal
    RemoteIPHeader X-Forwarded-For

    <Directory "C:\Users\Dev\Documents\angular-10\dist">
        DirectoryIndex index.html
    AllowOverride ALL
    Require all granted
    </Directory>
</VirtualHost>

如果我在下面删除,则网址会更改,但是我得到The requested URL /en-gb/ was not found on this server.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.html [L]

当前,URL不会更改为/ en-gb-我认为是因为RewriteRule . index.html [L]已将其删除

如何在保留此/ en-gb重写的同时从根目录提供index.html?

解决方法

....是否保留此/ en-gb重写?

如果您想更改URL,则它必须是外部“重定向”,而不是“重写”。

#does the folder AND file exist? (ie. /index.html & css/style.css)
#yes - serve it & pop out of htaccess
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

当前没有执行任何操作,因为同一请求无法映射到文件。这些条件需要进行“或”运算。在这种情况下,测试REQUEST_FILENAME比连接两个服务器变量更简单。

请尝试以下操作:

RewriteEngine On

#does the folder OR file exist? (ie. /index.html & css/style.css)
#yes - pop out of htaccess and allow Appache to serve it
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

#does the url already have a country flag set?
#no - add country flag (ie. http://angular.wlocal/ -> http://angular.wlocal/en-gb)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule !^en-gb/ /en-gb%{REQUEST_URI} [R=302,L]

#if file folder not found,serve index.html (ie. http://angular.wlocal/en-gb/this-does-not-exist -> should serve index.html)
RewriteRule . index.html [L]

/en-gb加上前缀...,可以通过在/en-gb中执行此检查来避免条件来检查其是否没有以RewriteRule为前缀 pattern ,并在 substitution 字符串中使用REQUEST_URI服务器变量而不是$1后向引用。对REDIRECT_STATUS环境变量的检查只是确保我们仅处理直接请求,而不是重写对index.html的请求。

在来自客户端的初始请求中,REDIRECT_STATUS环境变量为空(未设置)。但是,当请求被重写为index.html(通过以下规则)时,该环境变量将更新为200(如200 OK HTTP状态)。因此,通过检查此环境变量是否为空(即^$),我们可以避免处理规则以进行内部重写(在这种情况下将导致无限循环)。另一种选择是在后续重写中仅使用END标志(Apache 2.4+),以防止重写引擎循环,但是将来可能需要在其他重写中添加此标记,并且Apache版本尚未添加。 t实际上是在问题中指出的。

请注意,这是302(临时)重定向。如果要永久保留,则将其更改为301-但只有在确认它可以正常工作后,才能进行。否则,您可能会遇到缓存问题。

由于第一条规则已经执行了此检查,因此无需重新检查请求是否未映射到最后一条规则中的文件或目录。

此处不需要<IfModule mod_rewrite.c>包装器,应将其删除

如果我在下面删除,则网址会更改,但是

如果删除最后一条规则,则永远不会调用您的角度应用程序,因此您确实会得到404。而且,仅删除最后一条规则不会导致URL changing ,因为先前的规则仍然是重写,这里没有其他“重定向”?