删除查询字符串参数以创建更加用户友好的 URL

Remove query string parameter to create a more user-friendly URL

我有这个 .htaccess 文件,但我不知道 mod_rewrite、

RewriteEngine On
RewriteRule ^(.+[^/])/$ http://%{HTTP_HOST}/ [R=301,L]
RewriteCond %{THE_REQUEST} \s/([^.]+)\.php [NC]
RewriteRule ^ /%1 [NE,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)/?$ /.php  [L]

我想要实现的是 localhost/viewticket/${id} 而不是 localhost/viewticket.php?id=123

我尝试了很多 .htaccess 规则,但 none 有效,除了这个在我的 URL.

中隐藏 .php 的规则

确保您已更改内部 URL,以便链接到 /viewticket/<id>。然后在根 .htaccess 文件的顶部添加以下内容:

# Prevent MutliViews rewriting "viewticket" and omitting the URL parameter
Options -MultiViews

RewriteEngine On

# Redirect any direct requests to "/viewticket.php?id=<id>" to "/viewticket/<id>"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^id=(\d*)
RewriteRule ^(viewticket)\.php$ //%1 [R=301,L]

# Rewrite "/viewticket/<id>" to "viewticket.php?id=<id>"
RewriteRule ^(viewticket)/(\d*)$ .php?id= [QSA,L]

如果您不希望在您的“漂亮”/viewticket/<id> URL 上有任何查询字符串,请删除最后一条规则中的 QSA(查询字符串追加)标志。

</code> 是对 <code>RewriteRule 模式 中第一个捕获组(带括号的子模式)的反向引用。同样,%1 是对最后匹配的 CondPatternRewriteCond 指令)中第一个捕获组的反向引用。

始终首先使用 302(临时)重定向进行测试,以避免潜在的缓存问题,只有在您确定一切正常时才更改为 301(永久)重定向。测试前清除浏览器缓存。

参考:


补充:

RewriteEngine On
RewriteRule ^(.+[^/])/$ http://%{HTTP_HOST}/ [R=301,L]
RewriteCond %{THE_REQUEST} \s/([^.]+)\.php [NC]
RewriteRule ^ /%1 [NE,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)/?$ /.php  [L]

您现有的指令(删除尾部斜杠和 .php 扩展名)不太正确。

你的第一个规则 无条件地 删除尾部斜杠也将“尝试”从目录中删除尾部斜杠 - 这将与 mod_dir 和结果冲突在重定向循环中。正则表达式中间的否定字符 class [^/](匹配 non-slash 字符)似乎是多余的。这也重定向到 HTTP(不是 HTTPS)?

删除 .php 扩展名的第二条规则也将错误地匹配 .php 如果它出现在 [=89= 的查询字符串部分].例如。 /foo?bar.php 将被重定向到 /foo?bar。尽管正则表达式 ([^.]+) 确实避免了可能更常见的 /foo.php?bar.php 被错误重定向的情况。

如果您收到 /foo/bar 形式的请求,则通过内部重写附加 .php 扩展名的第三条规则可能会导致 rewrite-loop(500 内部服务器错误) /foo.php 存在于文件系统的根目录中。此外,(可选的)尾部斜杠也被捕获子组捕获,因为 * 量词是贪婪的。如果不是第一个删除尾部斜杠的规则,这也会导致格式错误的重写。 (但由于删除了尾部斜杠,因此此规则中的 可选 尾部斜杠是多余的。)

如果您仍然需要这些规则来删除结尾的斜杠和处理无扩展名 .php URL,那么请按如下方式使用这些规则。确保您已经在内部链接到无扩展名 URL。这些规则应该遵循我在上面发布的规则块。

# Remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/ [R=301,L]

# Remove ".php" extension if present on the initial request
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.+)\.php$ / [R=301,L]

# Append ".php" extension if request maps to a PHP file
RewriteCond %{DOCUMENT_ROOT}/.php -f
RewriteRule ^(.*?)/?$ .php  [L]

这些指令(以及您的原始指令)确实假定 .htaccess 文件位于文档根目录中。

您可以使用以下代码:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/$ .php
RewriteRule ^([^/]+)/([^/]+)/$ //.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/)$
RewriteRule (.*)$ // [R=301,L

如果它不起作用,您可以阅读此 PDF 文件:How to remove PHP or HTML extensions with htaccess

我为你制作了这个,擦掉你的然后复制这个享受吧^^

IndexIgnore */*

Options FollowSymLinks
AddDefaultCharset utf-8

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^viewticket/([^/]+)/?([^/]*)/?([^/]*)$ viewticket.php?id=&param2=&param3= [L]
    RewriteCond %{REQUEST_FILENAME}.php -f
    RewriteRule ^(.*)/?$ /.php  [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-l
    RewriteRule . index.php [L]
</IfModule>```