使用 .htaccess OpenLiteSpeed 服务器正确重定向 php id
Redirect php id Properly with .htaccess OpenLiteSpeed Server
我是 .htaccess 用法的新手,并试图通过在线资源学习,但是我写的规则相互抵消,我很难写出足够好的 .htaccess 文件,下面是我当前的 .htaccess 文件对于某些页面工作正常,例如删除扩展名和重写子域,请检查下面
## Flag for GoDaddy
Options +MultiViews
RewriteBase /
## Remove extensions
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !=f
RewriteRule ^([^\.]+)$ .php [NC,L]
## Redirect from extensions to non-extensions
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=301,NE,L]
## Redirect Pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^post/([a-zA-Z0-9-/]+)$ /post.php?ps=
RewriteRule ^([a-zA-Z0-9-/]+)$ post-files.php?ps= [L,QSA]
## Server Only
## Redirect from www - non-www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http:/// [R=301,L]
## SSL Redirect
## RewriteEngine On
## RewriteCond %{HTTPS} ≠On
## RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
## Create Error Pages
ErrorDocument 404 /errors/404.html
ErrorDocument 403 /errors/403.html
ErrorDocument 500 /errors/500.html
## Redirect non-existing pages to index.php
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
以上是我目前正在使用的 .htaccess,我是通过 youtube 上的教程得到它的
正如您在这条线上方看到的 RewriteRule ^post/([a-zA-Z0-9-/]+)$ /post.php?ps=
和它下方的线没有穿过 ps 但它们显示 404 页面
我希望结果是 domain.com/post-file-slug
以准确转到文件 domain.com/post-file.php?ps=post-slug-here
以获取规则 RewriteRule ^([a-zA-Z0-9-/]+)$ post-files.php?ps= [L,QSA]
和
domain.com/post/post-slug-here
精确到 domain.com/post.php?ps=post-slug-here
规则
RewriteRule ^post/([a-zA-Z0-9-/]+)$ /post.php?ps=
我已经为此工作了 2 天,希望尽快修复它。谢谢
## Flag for GoDaddy
Options +MultiViews
这在什么方面是“GoDaddy 的旗帜”?启用 MultiViews 将导致 ps
URL 参数不会传递给 post.php
脚本。您需要确保禁用 MultiViews,以便以后的重写能够按预期工作。即
Options -MultiViews
MultiViews(mod_negotiation 的一部分)本质上支持无扩展 URLs。这将导致 /post/post-slug-here
请求被“重写”为 /post.php/post-slug-here
在 你的 mod_rewrite 指令被处理之前,所以它永远不会匹配并且永远不会重写请求以包含 ps
URL 参数。
## Remove extensions
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !=f
RewriteRule ^([^\.]+)$ .php [NC,L]
## Redirect from extensions to non-extensions
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=301,NE,L]
目前是 MultiViews 允许您的无扩展 URLs 工作。上面的第一个 condition(RewriteCond
指令)是不正确的。它应该是 !-f
(不是文件),而不是 !=f
(不等于“f”——总是正确的)。但是,这仍然是“错误的”,因为您需要在重写请求之前检查 .php
文件是否存在。如果您简单地重写所有未映射到文件的请求(这是您在这里尝试做的),那么以后对 post.php
、post-files.php
和 index.php
的重写将不会被处理如预期。
第二个条件中的正则表达式\s/+(.+?)\.php[\s?]
并不严格正确,因为如果.php
出现在查询字符串中,它将导致格式错误的重定向URL-path中省略了。例如。对 /foo?bar.php
的请求将导致重定向到 /foo?bar
,而在这种情况下根本不应存在重定向。正则表达式只需要捕获 URL-path,因此将子模式 (.+?)
更改为 ([^?]+)
。
这两条规则也是反过来的。外部重定向应该是第一个。作为一般规则,外部重定向应始终在内部重写之前进行。
应该是这样的:
## Remove extensions
## Redirect to remove ".php" extension
RewriteCond %{THE_REQUEST} \s/+([^?]+?)\.php[\s?] [NC]
RewriteRule \.php$ /%1 [R=301,NE,L]
# Rewrite to append ".php" extension if corresponding ".php" file exists
RewriteCond %{DOCUMENT_ROOT}/.php -f
RewriteRule ^([^.]+)$ .php [L]
您应该已经链接到没有 .php
扩展名的文件。删除 .php
扩展名的重定向仅在更改现有 URL 结构时用于 SEO。
在正则表达式字符 class 中使用时,无需 backslash-escape 文字点。 NC
标志在这里是多余的。
## Redirect Pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^post/([a-zA-Z0-9-/]+)$ /post.php?ps=
RewriteRule ^([a-zA-Z0-9-/]+)$ post-files.php?ps= [L,QSA]
RewriteCond
指令仅适用于随后的第一个 RewriteRule
指令。所以,上面的第二条规则被无条件地处理——这是故意的吗?
其实那两个条件很可能是多余的。正则表达式似乎已经排除了实际文件,因为正则表达式排除了点。您是否需要能够直接访问文件系统目录?
class[a-zA-Z0-9-/]
这个字很“迷惑”。最后一个连字符被视为文字连字符(大概是本意),但乍一看它可能看起来像一个范围说明符(如前面字符 class 中所用)。为避免在匹配字符 class 内的文字连字符时出现混淆,可以 backslash-escape 它,或者将其移至字符 class 中的第一个或最后一个字符。例如。 [a-zA-Z0-9/-]
.
您还缺少第一条规则中的 L
标志。 (您已将其包括在第二个中。)您还需要 QSA
标志吗? (即,您是否希望初始请求有额外的 URL 参数?)
修改了上面的“extension removal”规则,这个倒是无所谓,但是这些重写request到post.php
和post-files.php
的规则应该是上面的“扩展删除”规则。
## Redirect from www - non-www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http:/// [R=301,L]
此规则不正确且位置错误。规范重定向(www 到 non-www 和 HTTP 到 HTTPS)通常应该高于其他规则。如上所述,重写前重定向。
但是这个规则也是完全不正确的。 </code> 是对 <code>RewriteRule
中第一个捕获的子模式的反向引用,因此 http:///
自然会导致格式错误的重定向。第一个反向引用应该是 %1
(到最后匹配的 CondPattern)以匹配请求的主机名。通常,您还应该在此处重定向到 HTTPS,而不是 HTTP。例如,规则应为:
:
RewriteRule (.*) https://%1/ [R=301,L]
围绕 RewriteRule
模式 的 ^
和 $
是多余的,因为默认情况下正则表达式是贪婪的。
## SSL Redirect
## RewriteEngine On
## RewriteCond %{HTTPS} ≠On
## RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
虽然注释掉了,但也是不正确的。它需要在其他重写之前进行。如果在 www 之后实现 HSTS 或 ,它应该位于文件的顶部,如果不是,则重定向到 non-www(并最小化重定向的数量)。
前面的condition中的CondPattern应该是!on
,而不是≠On
(完全无效在两个方面...≠
无效,比较结果为 case-sensitive。HTTPS
将始终为小写。)
您还缺少 R=301
和 L
标志。
RewriteRule
模式中不需要捕获组,因为替换字符串中没有使用它. ^
就足够了(而且效率更高)而不是 (.*)
。
## Create Error Pages
ErrorDocument 404 /errors/404.html
ErrorDocument 403 /errors/403.html
ErrorDocument 500 /errors/500.html
为了便于阅读,您应该在文件顶部定义您的自定义错误文档。 (从技术上讲,这并不重要。)
## Redirect non-existing pages to index.php
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
为了便于阅读,您应该在文件顶部一起定义 Options
(与 -MultiViews
)。例如:
Options -MultiViews -Indexex +SymLinksIfOwnerMatch
(禁用 Indexes
- auto-generated 目录列表 - 是个好主意。)
您不需要重复 RewriteEngine
指令。 (只有该指令的最后一个实例执行任何操作。)将此规则放在文件顶部附近、第一个 mod_rewrite 指令之前是合乎逻辑的。 (尽管从技术上讲,该指令在文件中的位置实际上并不重要。)
旁白:您在内部重写时使用的前缀应该保持一致。在某些规则中,您包括斜杠前缀(例如 /post.php
),而在某些规则中您省略了它(post-files.php
)。您已经定义了 RewriteBase /
(这里并不是严格要求的)- RewriteBase
仅适用于相对替换字符串(即省略斜杠前缀时)。
更新:
also i have file i want to exclude like 404.php in root directory from how do i exclude somefiles from the redirect. when i sent ajax to backend php file it redirected to homepage and failed to retrieve data.
要排除特定文件,您可以添加如下规则,在规范重定向之后:
# Exclude "/404.php" from stripping the ".php" extension
RewriteRule ^404\.php$ - [L]
一般来说,一旦您为 .php
文件设置了无扩展名,您就应该无处不在。因此,不应有意外的重定向。重定向实际上仅用于 SEO。
关于您的 AJAX 请求,如果您正在发出 POST 请求,那么您可以简单地从进一步处理中排除所有 POST 请求。例如:
# Prevent further processing of POST requests to ".php" files
RewriteCond %{REQUEST_METHOD} POST [NC]
RewriteRule \.php$ - [L]
或者(或同时),如果您的 AJAX 请求正在设置自定义 HTTP 请求 header 那么您也可以检查它。
总结
综合以上几点,应该是这样的:
## Disable MultiViews and Indexes
Options -MultiViews -Indexes +SymLinksIfOwnerMatch
## Create Error Pages
ErrorDocument 404 /errors/404.html
ErrorDocument 403 /errors/403.html
ErrorDocument 500 /errors/500.html
RewriteEngine On
RewriteBase /
#### Canonical redirects
## SSL Redirect
## RewriteCond %{HTTPS} !on
## RewriteRule (.*) https://%{HTTP_HOST}/ [R=301,L]
## Redirect from www - non-www
## >>> CHANGE TO "HTTPS://"
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule (.*) http://%1/ [R=301,L]
#### Rewrite Pages
RewriteRule ^post/([a-zA-Z0-9/-]+)$ post.php?ps= [QSA,L]
RewriteRule ^([a-zA-Z0-9/-]+)$ post-files.php?ps= [QSA,L]
#### Exceptions
## Exclude "/404.php" from stripping the ".php" extension
RewriteRule ^404\.php$ - [L]
## Prevent further processing of POST requests to ".php" files
RewriteCond %{REQUEST_METHOD} POST [NC]
RewriteRule \.php$ - [L]
#### Remove extensions
## Redirect to remove ".php" extension
RewriteCond %{THE_REQUEST} \s/+([^?]+)\.php[\s?] [NC]
RewriteRule \.php$ /%1 [R=301,NE,L]
## Rewrite to append ".php" extension if corresponding ".php" file exists
RewriteCond %{DOCUMENT_ROOT}/.php -f
RewriteRule ^([^.]+)$ .php [L]
## Redirect non-existing pages to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
我是 .htaccess 用法的新手,并试图通过在线资源学习,但是我写的规则相互抵消,我很难写出足够好的 .htaccess 文件,下面是我当前的 .htaccess 文件对于某些页面工作正常,例如删除扩展名和重写子域,请检查下面
## Flag for GoDaddy
Options +MultiViews
RewriteBase /
## Remove extensions
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !=f
RewriteRule ^([^\.]+)$ .php [NC,L]
## Redirect from extensions to non-extensions
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=301,NE,L]
## Redirect Pages
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^post/([a-zA-Z0-9-/]+)$ /post.php?ps=
RewriteRule ^([a-zA-Z0-9-/]+)$ post-files.php?ps= [L,QSA]
## Server Only
## Redirect from www - non-www
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http:/// [R=301,L]
## SSL Redirect
## RewriteEngine On
## RewriteCond %{HTTPS} ≠On
## RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
## Create Error Pages
ErrorDocument 404 /errors/404.html
ErrorDocument 403 /errors/403.html
ErrorDocument 500 /errors/500.html
## Redirect non-existing pages to index.php
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
以上是我目前正在使用的 .htaccess,我是通过 youtube 上的教程得到它的
正如您在这条线上方看到的 RewriteRule ^post/([a-zA-Z0-9-/]+)$ /post.php?ps=
和它下方的线没有穿过 ps 但它们显示 404 页面
我希望结果是 domain.com/post-file-slug
以准确转到文件 domain.com/post-file.php?ps=post-slug-here
以获取规则 RewriteRule ^([a-zA-Z0-9-/]+)$ post-files.php?ps= [L,QSA]
和
domain.com/post/post-slug-here
精确到 domain.com/post.php?ps=post-slug-here
规则
RewriteRule ^post/([a-zA-Z0-9-/]+)$ /post.php?ps=
我已经为此工作了 2 天,希望尽快修复它。谢谢
## Flag for GoDaddy Options +MultiViews
这在什么方面是“GoDaddy 的旗帜”?启用 MultiViews 将导致 ps
URL 参数不会传递给 post.php
脚本。您需要确保禁用 MultiViews,以便以后的重写能够按预期工作。即
Options -MultiViews
MultiViews(mod_negotiation 的一部分)本质上支持无扩展 URLs。这将导致 /post/post-slug-here
请求被“重写”为 /post.php/post-slug-here
在 你的 mod_rewrite 指令被处理之前,所以它永远不会匹配并且永远不会重写请求以包含 ps
URL 参数。
## Remove extensions RewriteEngine On RewriteCond %{REQUEST_FILENAME} !=f RewriteRule ^([^\.]+)$ .php [NC,L] ## Redirect from extensions to non-extensions RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC] RewriteRule ^ /%1 [R=301,NE,L]
目前是 MultiViews 允许您的无扩展 URLs 工作。上面的第一个 condition(RewriteCond
指令)是不正确的。它应该是 !-f
(不是文件),而不是 !=f
(不等于“f”——总是正确的)。但是,这仍然是“错误的”,因为您需要在重写请求之前检查 .php
文件是否存在。如果您简单地重写所有未映射到文件的请求(这是您在这里尝试做的),那么以后对 post.php
、post-files.php
和 index.php
的重写将不会被处理如预期。
第二个条件中的正则表达式\s/+(.+?)\.php[\s?]
并不严格正确,因为如果.php
出现在查询字符串中,它将导致格式错误的重定向URL-path中省略了。例如。对 /foo?bar.php
的请求将导致重定向到 /foo?bar
,而在这种情况下根本不应存在重定向。正则表达式只需要捕获 URL-path,因此将子模式 (.+?)
更改为 ([^?]+)
。
这两条规则也是反过来的。外部重定向应该是第一个。作为一般规则,外部重定向应始终在内部重写之前进行。
应该是这样的:
## Remove extensions
## Redirect to remove ".php" extension
RewriteCond %{THE_REQUEST} \s/+([^?]+?)\.php[\s?] [NC]
RewriteRule \.php$ /%1 [R=301,NE,L]
# Rewrite to append ".php" extension if corresponding ".php" file exists
RewriteCond %{DOCUMENT_ROOT}/.php -f
RewriteRule ^([^.]+)$ .php [L]
您应该已经链接到没有 .php
扩展名的文件。删除 .php
扩展名的重定向仅在更改现有 URL 结构时用于 SEO。
在正则表达式字符 class 中使用时,无需 backslash-escape 文字点。 NC
标志在这里是多余的。
## Redirect Pages RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^post/([a-zA-Z0-9-/]+)$ /post.php?ps= RewriteRule ^([a-zA-Z0-9-/]+)$ post-files.php?ps= [L,QSA]
RewriteCond
指令仅适用于随后的第一个 RewriteRule
指令。所以,上面的第二条规则被无条件地处理——这是故意的吗?
其实那两个条件很可能是多余的。正则表达式似乎已经排除了实际文件,因为正则表达式排除了点。您是否需要能够直接访问文件系统目录?
class[a-zA-Z0-9-/]
这个字很“迷惑”。最后一个连字符被视为文字连字符(大概是本意),但乍一看它可能看起来像一个范围说明符(如前面字符 class 中所用)。为避免在匹配字符 class 内的文字连字符时出现混淆,可以 backslash-escape 它,或者将其移至字符 class 中的第一个或最后一个字符。例如。 [a-zA-Z0-9/-]
.
您还缺少第一条规则中的 L
标志。 (您已将其包括在第二个中。)您还需要 QSA
标志吗? (即,您是否希望初始请求有额外的 URL 参数?)
修改了上面的“extension removal”规则,这个倒是无所谓,但是这些重写request到post.php
和post-files.php
的规则应该是上面的“扩展删除”规则。
## Redirect from www - non-www RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] RewriteRule ^(.*)$ http:/// [R=301,L]
此规则不正确且位置错误。规范重定向(www 到 non-www 和 HTTP 到 HTTPS)通常应该高于其他规则。如上所述,重写前重定向。
但是这个规则也是完全不正确的。 </code> 是对 <code>RewriteRule
中第一个捕获的子模式的反向引用,因此 http:///
自然会导致格式错误的重定向。第一个反向引用应该是 %1
(到最后匹配的 CondPattern)以匹配请求的主机名。通常,您还应该在此处重定向到 HTTPS,而不是 HTTP。例如,规则应为:
:
RewriteRule (.*) https://%1/ [R=301,L]
围绕 RewriteRule
模式 的 ^
和 $
是多余的,因为默认情况下正则表达式是贪婪的。
## SSL Redirect ## RewriteEngine On ## RewriteCond %{HTTPS} ≠On ## RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
虽然注释掉了,但也是不正确的。它需要在其他重写之前进行。如果在 www 之后实现 HSTS 或 ,它应该位于文件的顶部,如果不是,则重定向到 non-www(并最小化重定向的数量)。
前面的condition中的CondPattern应该是!on
,而不是≠On
(完全无效在两个方面...≠
无效,比较结果为 case-sensitive。HTTPS
将始终为小写。)
您还缺少 R=301
和 L
标志。
RewriteRule
模式中不需要捕获组,因为替换字符串中没有使用它. ^
就足够了(而且效率更高)而不是 (.*)
。
## Create Error Pages ErrorDocument 404 /errors/404.html ErrorDocument 403 /errors/403.html ErrorDocument 500 /errors/500.html
为了便于阅读,您应该在文件顶部定义您的自定义错误文档。 (从技术上讲,这并不重要。)
## Redirect non-existing pages to index.php Options +SymLinksIfOwnerMatch RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L]
为了便于阅读,您应该在文件顶部一起定义 Options
(与 -MultiViews
)。例如:
Options -MultiViews -Indexex +SymLinksIfOwnerMatch
(禁用 Indexes
- auto-generated 目录列表 - 是个好主意。)
您不需要重复 RewriteEngine
指令。 (只有该指令的最后一个实例执行任何操作。)将此规则放在文件顶部附近、第一个 mod_rewrite 指令之前是合乎逻辑的。 (尽管从技术上讲,该指令在文件中的位置实际上并不重要。)
旁白:您在内部重写时使用的前缀应该保持一致。在某些规则中,您包括斜杠前缀(例如 /post.php
),而在某些规则中您省略了它(post-files.php
)。您已经定义了 RewriteBase /
(这里并不是严格要求的)- RewriteBase
仅适用于相对替换字符串(即省略斜杠前缀时)。
更新:
also i have file i want to exclude like 404.php in root directory from how do i exclude somefiles from the redirect. when i sent ajax to backend php file it redirected to homepage and failed to retrieve data.
要排除特定文件,您可以添加如下规则,在规范重定向之后:
# Exclude "/404.php" from stripping the ".php" extension
RewriteRule ^404\.php$ - [L]
一般来说,一旦您为 .php
文件设置了无扩展名,您就应该无处不在。因此,不应有意外的重定向。重定向实际上仅用于 SEO。
关于您的 AJAX 请求,如果您正在发出 POST 请求,那么您可以简单地从进一步处理中排除所有 POST 请求。例如:
# Prevent further processing of POST requests to ".php" files
RewriteCond %{REQUEST_METHOD} POST [NC]
RewriteRule \.php$ - [L]
或者(或同时),如果您的 AJAX 请求正在设置自定义 HTTP 请求 header 那么您也可以检查它。
总结
综合以上几点,应该是这样的:
## Disable MultiViews and Indexes
Options -MultiViews -Indexes +SymLinksIfOwnerMatch
## Create Error Pages
ErrorDocument 404 /errors/404.html
ErrorDocument 403 /errors/403.html
ErrorDocument 500 /errors/500.html
RewriteEngine On
RewriteBase /
#### Canonical redirects
## SSL Redirect
## RewriteCond %{HTTPS} !on
## RewriteRule (.*) https://%{HTTP_HOST}/ [R=301,L]
## Redirect from www - non-www
## >>> CHANGE TO "HTTPS://"
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule (.*) http://%1/ [R=301,L]
#### Rewrite Pages
RewriteRule ^post/([a-zA-Z0-9/-]+)$ post.php?ps= [QSA,L]
RewriteRule ^([a-zA-Z0-9/-]+)$ post-files.php?ps= [QSA,L]
#### Exceptions
## Exclude "/404.php" from stripping the ".php" extension
RewriteRule ^404\.php$ - [L]
## Prevent further processing of POST requests to ".php" files
RewriteCond %{REQUEST_METHOD} POST [NC]
RewriteRule \.php$ - [L]
#### Remove extensions
## Redirect to remove ".php" extension
RewriteCond %{THE_REQUEST} \s/+([^?]+)\.php[\s?] [NC]
RewriteRule \.php$ /%1 [R=301,NE,L]
## Rewrite to append ".php" extension if corresponding ".php" file exists
RewriteCond %{DOCUMENT_ROOT}/.php -f
RewriteRule ^([^.]+)$ .php [L]
## Redirect non-existing pages to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]