将子文件夹重定向到root并将其隐藏在URL中

时间:2016-09-23 17:26:38

标签: apache .htaccess redirect mod-rewrite

我已经设法" rebase"由于this answerthis answer,目录中的根目录可以将公共文件与配置,帮助程序和控制器分开。

但是我意识到,如果用户输入http://domain.com/public它不会重定向到http://domain.com,这对SEO有害,因为机器人会将它们视为两个网址,因此会重复。

我需要301将/public重定向到root,但只要我正在尝试。它没有用。

我的htaccess如下所示:

# Options
Options +FollowSymLinks +MultiViews -Indexes
DirectorySlash off

# Enable Rewrite Engine
RewriteEngine on
RewriteBase /

# Exceptions
RewriteCond %{REQUEST_URI} ^/(images|javascripts|stylesheets)/ [NC]
RewriteRule ^ - [L]

# www to non-www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteCond %{HTTPS}s ^on(s)|
RewriteRule ^ http%2://%1%{REQUEST_URI} [L,R=301]

# Make /public like it was root
RewriteCond %{THE_REQUEST} /public/([^\s]+) [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_URI} !^/public
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /public/$1 [NC,L,QSA]

# Error pages
ErrorDocument 403 /errors/403.php
ErrorDocument 404 /errors/404.php
ErrorDocument 500 /errors/500.php

<files .htaccess="">
  order allow,deny
  deny from all
</files>

通过这种方式,它会重定向到http://domain.com//

如何解决此问题?

修改

我的网站目录结构是:

·
|__data
|__controllers
|__helpers
|__partials
|__layouts
|__images
|__javascripts
|__stylesheets
|__public
   |__index.php
   |__subfolder
      |__index.php

在root中,不会有任何index.php页面。因此,我需要制作/public目录,因为它是我的根目录,以便保留用户不必看到分开的配置和其他目录。

3 个答案:

答案 0 :(得分:2)

将您的2 public/相关规则替换为:

# add a trailing slash if public/$1 is a directory
RewriteCond %{DOCUMENT_ROOT}/public/$1 -d
RewriteRule ^(.*?[^/])$ %{REQUEST_URI}/ [L,R=301,NE]

# Make /public like it was root
RewriteCond %{THE_REQUEST} \s/+public/(\S*)\s [NC]
RewriteRule ^ /%1 [L,R=301,NE]

# internally add public/ to URIs
RewriteRule ^(?!public/).*$ public/$0 [L,NC]

如果您使用子目录的URL,则不使用第一个尾随斜杠添加规则,例如http://domain.com/subfolder然后在第3个规则之后,在URI中添加public/,它在内部变为http://domain.com/public/subfolder,这是一个有效的目录,而Apache的mod_dir模块最后添加一个尾随斜杠,执行{{1} 1}}重定向到301,这将公开 http://domain.com/public/subfolder/部分给您的客户。

当第一个尾随斜杠出现时,我们会检查目的地是否为目录,并在原始 public/网址中添加一个尾部斜杠。

答案 1 :(得分:1)

这里有很多你需要解决的问题,但它的核心似乎在这里:

# Make /public like it was root
RewriteCond %{THE_REQUEST} /public/([^\s]+) [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_URI} !^/public
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /public/$1 [NC,L,QSA]

该块将生成一个循环。它说&#34;如果URL包含public,则将其重定向到root,但如果它不包含public,则将其重定向到public&#34;。

我认为你要做的只是:

RewriteRule ^public/(.*) /$1 [R=301,L]

还值得指出的是,你底部的区块不会做任何事情。我怀疑你的意思是:

<Files .htaccess>

但是,为了更好的衡量标准,您可以尝试

<FilesMatch ^\.>

适用于所有&#34;点文件&#34;。

答案 2 :(得分:1)

好的,通过你的编辑,现在看起来你正在问我最初如何解释它。它看起来像是在引入一层额外的复杂性,以便保护不应该在文档目录中的文件。

我建议的是从安全角度而不是httpd配置角度。如果文件不是公共文件,请将它们移出文档目录。你最终会得到你的常规内容,以及文档目录中的图像,js和css,以及其他内容。

如果不这样做,如果你坚持使用mod_rewrite来实现这一目标,我建议如下:

RewriteCond %{DOCUMENT_ROOT}public%{REQUEST_FILENAME} -f
RewriteRule ^ /public%{REQUEST_URI} [PT]

然而,请注意,这实际上并没有解决问题,因为文档目录中仍然存在“私有”内容,等待有人知道如何获取它。

我建议你退后一步,找出你实际想要解决的问题。如果私有文件存在于文档根目录中,那么正确的解决方案是将它们移出该文档根目录,而不是尝试在那里路由它们。