.htaccess - 将所有内容静默重写/重定向到内部子文件夹

Posted

技术标签:

【中文标题】.htaccess - 将所有内容静默重写/重定向到内部子文件夹【英文标题】:.htaccess - silently rewrite/redirect everything to internal subfolder 【发布时间】:2014-12-11 20:49:08 【问题描述】:

假设我有这个www.example.com 网站结构:

/srv/http/
/srv/http/site/index.php
/srv/http/site/stuff.php

我希望发生以下重写/重定向:

www.example.com/index.php -> 重定向到 -> www.example.com/site/index.php -> 但用户看到了 -> www.example.com/index.php

www.example.com/stuff.php -> 重定向到 -> www.example.com/site/stuff.php -> 但用户看到了 -> www.example.com/stuff.php

一般来说,www.example.com/ 之后的所有内容都会重定向到 www.example.com/site/。但用户在浏览器中看到的是原始 URL。

我在互联网上四处寻找,但没有弄清楚在这种特殊情况下该使用什么。

我尝试重写所有内容:

RewriteEngine On
RewriteRule ^$ /site [L]

index.php 消失了,www.example.com/site/ 显示给用户。

如何使用.htaccess 来解决这个问题?

【问题讨论】:

为什么不把 DocumentRoot 移到 .../site ? 以下任何答案对您有用吗? 这很奇怪。如果您没有使用 [R] 标志,则不应重定向浏览器,因此不应向用户显示 www.example.com/site/。我很想在你重写之前考虑其他东西,比如 ErrorDocument 404 规则 - 因为 /index.php 和 /stuff.php 在那个位置并不真正存在 嗯,更正我之前的评论:如果你没有使用 [R] 标志,但你的 RewriteUrl 返回一个完整的 url,浏览器也会被重定向。 【参考方案1】:

您需要捕获传入服务器的 url 请求,如下所示:

RewriteEngine On
RewriteCond %REQUEST_URI !^/site/
RewriteRule ^(.*)$ /site/$1 [L,QSA]

QSA(最终)也将查询字符串附加到重写的 url

【讨论】:

这个重写规则出现内部服务器错误 我也是。虽然 RewriteRule ^foo$ /bar/$1 [L,QSA] 没有重写条件有效【参考方案2】:

与@guido 建议的想法相同,但使用负前瞻有点缩短

RewriteEngine On
RewriteRule ^(?!site/)(.*)$ site/$1 [L]

注意:我没有使用 QSA 标志,因为我们没有向替换 URL 的查询字符串添加其他参数。默认情况下,Apache 会将原始查询字符串与替换 URL 一起传递。

http://www.example.com/index.php?one=1&two=2 

将在内部重写为

http://www.example.com/site/index.php?one=1&two=2

如果您真的想在每次重写的查询字符串中添加一个特殊参数(例如:mode=rewrite),那么您可以使用QSA 查询字符串追加标志

RewriteEngine On
RewriteRule ^(?!site/)(.*)$ site/$1?mode=rewrite [L,QSA]

然后这会将mode=rewrite 与原始查询字符串结合起来

http://www.example.com/index.php?one=1&two=2 

http://www.example.com/site/index.php?mode=rewrite&one=1&two=2 

【讨论】:

在我的情况下这不起作用,额外的查询参数不会自动发送,所以我必须添加 QSA 才能获得正常的 GET 参数。我想这取决于服务器配置(在我的例子中是 XAMPP)【参考方案3】:
RewriteEngine On

RewriteRule ^(.*)$ site/index.php?var=$1 [L]

使用这条规则,我将所有请求传递给 site/index.php,因此您可以通过 $_GET['var'] 获取请求的 uri,然后您将使 index.php 服务于请求的 url幕后没有改变用户浏览器中的 url。咻。

【讨论】:

此解决方案是否要求请求者代理在新地址再次加载资源(外部重定向),还是直接返回新地址的资源(内部重定向)? Web 上的很多重定向解决方案都没有包含这些信息,这很重要,不仅因为它会影响浏览器地址栏和历史记录中出现的地址,还因为某些代理不是浏览器,不会响应带有第二个请求。

以上是关于.htaccess - 将所有内容静默重写/重定向到内部子文件夹的主要内容,如果未能解决你的问题,请参考以下文章

页面未正确重定向 - HTTPS HTACCESS 重写错误

htaccess 将旧域重定向到新域

.htaccess - 将所有 URL + 现有目录重定向到 index.php

htaccess 重定向 301 + 重写冲突

目录存在时htaccess重写url重定向

.htaccess 结合 301 重定向和 URI 重写