mod-rewrite删除文件扩展名,加上斜线,去除WWW和重定向到404,如果没有文件/目录可用 [英] mod rewrite to remove file extension, add trailing slash, remove www and redirect to 404 if no file/directory is available

查看:311
本文介绍了mod-rewrite删除文件扩展名,加上斜线,去除WWW和重定向到404,如果没有文件/目录可用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的.htaccess文件中创建重写规则执行以下操作:

I would like to create rewrite rules in my .htaccess file to do the following:

  • 在通过domain.com/abc.php访问:删除文件扩展名,添加斜线并加载abc.php文件。 URL应该像这样修改后:domain.com/abc /

  • When accessed via domain.com/abc.php: remove the file extension, append a trailing slash and load the abc.php file. url should look like this after rewrite: domain.com/abc/

在通过domain.com/abc/访问:离开网址是和负载abc.php

When accessed via domain.com/abc/: leave the url as is and load abc.php

在通过domain.com/abc访问:追加斜线和负载abc.php。 URL应该像这样修改后:domain.com/abc /

When accessed via domain.com/abc: append trailing slash and load abc.php. url should look like this after rewrite: domain.com/abc/

删除WWW

重定向到404页(404.php)访问时URL不解析为文件夹或文件,例如:访问无论是domain.com/nothingthere.php或domain.com/nothingthere/或domain.com/nothingthere

Redirect to 404 page (404.php) when accessed url doesn't resolve to folder or file, e.g. when accessing either domain.com/nothingthere.php or domain.com/nothingthere/ or domain.com/nothingthere

请一些常驻301重定向从旧的URL到新的(如domain.com/abc.html到domain.com/abc~~V /)

Make some permanent 301 redirects from old urls to new ones (e.g. domain.com/abc.html to domain.com/abc/)

所有的PHP文件坐在文档根目录,但如果有一个解决方案,这将使的网址,如domain.com/abc/def/(将加载domain.com/abc/def.php)工作也将是巨大的,但是没有必要

All php files sit in the document root directory, but if there is a solution that would make urls such as domain.com/abc/def/ (would load domain.com/abc/def.php) also work it would be great as well, but not necessary

因此​​,这里是我的时刻(扔在一起从各种来源和样品来自网络的

So here is what I have at the moment (thrown together from various sources and samples from around the web

<IfModule mod_rewrite.c>
  RewriteCond %{HTTPS} !=on
  # redirect from www to non-www
  RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
  RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]

  # remove php file extension
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{THE_REQUEST} ^GET\ /[^?\s]+\.php
  RewriteRule (.*)\.php$ /$1/ [L,R=301]

  # add trailing slash
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteRule ^.*[^/]$ /$0/ [L,R=301]

  # resolve urls to matching php files 
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule (.*)/$ $1.php [L]

通过这首四点要求似乎工作,我是否进入domain.com/abc.php,domain.com/abc/或domain.com/abc,最终的URL总是最终被domain.com/abc/和domain.com/abc.php被加载。

With this the first four requirements seem to work, whether I enter domain.com/abc.php, domain.com/abc/ or domain.com/abc, the final url always ends up being domain.com/abc/ and domain.com/abc.php is loaded.

当我输入一个URL解析到不存在的,我得到一个错误310(重定向循环)的文件,当一个真正的404页应加载。此外,我还没有试过,如果子文件夹的工作,但正如我所说,这是低优先级。我是pretty的肯定,我可以只拍了永久的301重定向的最重要的是没有任何问题的,以及传统的网址,只是想提到它。所以,真正的问题是真正的非工作404页。

When I enter a url that resolves to a file that doesn't exists I'm getting an error 310 (redirect loop), when really a 404 page should be loaded. Additionally I haven't tried if subfolders work, but as I said, that's low priority. I'm pretty sure I can just slap the permanent 301 redirects for legacy urls on top of that without any issues as well, just wanted to mention it. So the real issue is really the non working 404 page.

推荐答案

我有问题越来越ErrorDocument来与重写错误可靠地工作,所以我倾向于preFER在我重写级联正确处理无效的页面。我试图覆盖范围完全与此测试向量。没有找到任何空隙。

I've had problems with getting ErrorDocument to work reliably with rewrite errors, so I tend to prefer to handle invalid pages correctly in my rewrite cascade. I've tried to cover a fully range of test vectors with this. Didn't find any gaps.

一些一般性的要点:

  • 您需要使用 DOCUMENT_ROOT 环境变量,在此。不幸的是,如果你使用一个共享的主机服务,那么这也没有设置正确重写执行过程中,使托管服务提供商建立了一个影子变量做同样的工作。矿用 DOCUMENT_ROOT_REAL ,但我也碰到过 PHP_DOCUMENT_ROOT 。做一个的phpinfo找出用什么为您服务。
  • 有一个调试信息的规则,你可以,只要修剪为您更换 DOCROOT 适当
  • 您不能总是用%{REQUEST_FILENAME} ,你会期望。这是因为,如果URI映射到 DOCROOT / somePathThatExists /名/ theRest %{REQUEST_FILENAME} 设置为 DOCROOT / somePathThatExists /名称,而不是等同于规则匹配字符串的整个模式。
  • 这是每目录,因此没有领先斜线,我们需要认识到,重写引擎将循环在的.htaccess 文件,直到一个不匹配停发生。
  • 在此处理所有有效组合,并在最后重定向到 404.php 我以为套404状态以及显示错误页面。
  • 将目前德code someValidScript.php / otherRubbish在SEO的方式,但额外的逻辑可以选择这一个好了。
  • You need to use the DOCUMENT_ROOT environment variable in this. Unfortunately if you use a shared hosting service then this isn't set up correctly during rewrite execution, so hosting providers set up a shadow variable to do the same job. Mine uses DOCUMENT_ROOT_REAL, but I've also come across PHP_DOCUMENT_ROOT. Do a phpinfo to find out what to use for your service.
  • There's a debug info rule that you can trim as long as you replace DOCROOT appropriately
  • You can't always use %{REQUEST_FILENAME} where you'd expect to. This is because if the URI maps to DOCROOT/somePathThatExists/name/theRest then the %{REQUEST_FILENAME} is set to DOCROOT/somePathThatExists/name rather than the full pattern equivalent to the rule match string.
  • This is "Per Directory" so no leading slashes and we need to realise that the rewrite engine will loop on the .htaccess file until a no-match stop occurs.
  • This processes all valid combinations and at the very end redirects to the 404.php which I assume sets the 404 Status as well as displaying the error page.
  • It will currently decode someValidScript.php/otherRubbish in the SEO fashion, but extra logic can pick this one up as well.

因此​​,这里的的.htaccess 片段:

So here is the .htaccess fragment:

Options -Indexes -MultiViews
AcceptPathInfo Off

RewriteEngine On
RewriteBase   /

## Looping stop.  Not needed in Apache 2.3 as this introduces the [END] flag
RewriteCond %{ENV:REDIRECT_END}  =1
RewriteRule ^                    -                       [L,NS]

## 302 redirections ##

RewriteRule ^ - [E=DOCROOT:%{ENV:DOCUMENT_ROOT_REAL},E=URI:%{REQUEST_URI},E=REQFN:%{REQUEST_FILENAME},E=FILENAME:%{SCRIPT_FILENAME}]

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

# remove php file extension on GETs (no point in /[^?\s]+\.php as rule pattern requires this)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_METHOD}   =GET
RewriteRule (.*)\.php$          $1/                      [L,R=301]

# add trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*[^/]$            $0/                      [L,R=301]

# terminate if file exists.  Note this match may be after internal redirect.
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^                   -                        [L,E=END:1]

# terminate if directory index.php exists.  Note this match may be after internal redirect.
RewriteCond %{REQUEST_FILENAME}    -d
RewriteCond %{ENV:DOCROOT}/$1/index.php    -f
RewriteRule ^(.*)(/?)$             $1/index.php          [L,NS,E=END:1]

# resolve urls to matching php files 
RewriteCond %{ENV:DOCROOT}/$1.php  -f
RewriteRule ^(.*?)/?$              $1.php                [L,NS,E=END:1]

# Anything else redirect to the 404 script.  This one does have the leading /

RewriteRule ^                      /404.php              [L,NS,E=END:1]

享受: - )

Enjoy :-)

这篇关于mod-rewrite删除文件扩展名,加上斜线,去除WWW和重定向到404,如果没有文件/目录可用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆