使用 mod_rewrite 将 301 重定向 get vars 到新的干净 URL

发布于 2025-01-03 06:36:46 字数 2934 浏览 0 评论 0原文

更新:解决方案在底部。

我最近从使用 index.php?p=page_name&o=temporary_override 等设置转为使用 /page_name/temporary_override 等干净的网址。临时覆盖只是为了让我可以在网站构建时看到网站更改的结果。

我目前将 mod_rewrite 设置为:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]

它将捕获“子目录”,然后 PHP 从 GHPAGE $_GET var 解析 URL。我想要的是设置 301 重定向,以便任何使用 index.php?p=something&o=something_else 的人都将被重定向到 /something/something_else。知道我怎样才能做到这一点吗?该p& o 可以按任何顺序出现,并且其中之一可能不存在。

编辑:好的,在 @Jon-Lin、@dambrisco 和 @anubhava 的帮助下,我已经更接近了。我的 .htaccess 文件现在看起来像:

RewriteEngine On
#Base Directory
RewriteBase /test/

#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^index\.php$ /%4/%5 [R=301,L]
#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^index\.php$ /%4 [R=301,L]
#Remove index.php
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*index\.php\ HTTP\/
RewriteRule ^index\.php$ / [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]

它现在正在重定向,但还没有到达需要去的地方。 root/test/index.php?p=test&o=override 现在重定向到 root/test/override?p=test&o=override。更接近,但我不知道如何摆脱添加到 URL 的 GET 变量,也不知道为什么它重定向到根目录而不是 RewriteBase 目录。

编辑:

它现在可以正确重定向,但由于某种原因,它从等式中删除了 /test/ RewriteBase 文件夹。 http://www.domain.com/test/index.php?p=page1&o=operation 正在重定向到 http://www.domain.com/page1/operation。新的.htaccess 文件如下:

RewriteEngine On

RewriteBase /test/

#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^ /%4/%5? [R=301,L]

#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^ /%4? [R=301,L]

#if index.php
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*index\.php\ HTTP\/
RewriteRule ^index\.php$ /$ [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]

谢谢大家。问题已经解决了。最终的 .htaccess 如下供参考。

RewriteEngine On

RewriteBase /test/

#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^ %4/%5? [R=301,L]

#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^ %4? [R=301,L]

#if index.php
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*index\.php\ HTTP\/
RewriteRule ^index\.php$ ? [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]

UPDATE: Solution at bottom.

I recently switched from using a set up such as index.php?p=page_name&o=temporary_override and switched to clean urls such as /page_name/temporary_override. The temporary override is just so I can see the results of the site changes while it's being built.

I currently have mod_rewrite set to:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]

Which will capture the "subdirectories" and then PHP parses the URL from the GHPAGE $_GET var. What I want is to set up a 301 redirect so that anyone using index.php?p=something&o=something_else will get redirected to /something/something_else. Any idea how I can accomplish this? The p & o may come in any order and one or the other may not exist.

EDIT: Ok, after help from @Jon-Lin, @dambrisco, and @anubhava, I have gotten closer. My .htaccess file now looks like:

RewriteEngine On
#Base Directory
RewriteBase /test/

#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^index\.php$ /%4/%5 [R=301,L]
#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^index\.php$ /%4 [R=301,L]
#Remove index.php
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*index\.php\ HTTP\/
RewriteRule ^index\.php$ / [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]

It is now redirecting, but not quite where it needs to go. root/test/index.php?p=test&o=override now redirects to root/test/override?p=test&o=override. Closer, but I can't figure out how to get rid of the GET vars which are being added to the URL or why it's redirecting to the root directory instead of to the RewriteBase directory.

EDIT:

It's now redirecting properly, but for some reason it's dropping the /test/ RewriteBase folder from the equation. http://www.domain.com/test/index.php?p=page1&o=operation is getting redirected to http://www.domain.com/page1/operation. New .htaccess file is below:

RewriteEngine On

RewriteBase /test/

#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^ /%4/%5? [R=301,L]

#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^ /%4? [R=301,L]

#if index.php
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*index\.php\ HTTP\/
RewriteRule ^index\.php$ /$ [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]

Thanks everyone. Question has been solved. Final .htaccess is below for reference.

RewriteEngine On

RewriteBase /test/

#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^ %4/%5? [R=301,L]

#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^ %4? [R=301,L]

#if index.php
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*index\.php\ HTTP\/
RewriteRule ^index\.php$ ? [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?GHPAGE=$1 [L,QSA]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情深如许 2025-01-10 06:36:46

将其添加到 htaccess 中的某个位置:

RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /index\.php\?p=([^&]+)&o=(.+)\ HTTP
RewriteRule index.php /%2/%3 [R=301,L]

如果您想涵盖没有“temporary_override”的情况,也请添加以下内容:

RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /index\.php\?p=(.+)\ HTTP
RewriteRule index.php /%2 [R=301,L]

更接近,但我不知道如何摆脱添加到 URL 的 GET 变量,也不知道为什么它重定向到根目录而不是 RewriteBase 目录

/%4/%5 末尾以删除查询字符串。并从 /%4/%5 中删除前导 /,以防止其重写到根目录。因此,例如,您的规则之一应如下所示:

RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^index\.php$ %4/%5? [R=301,L]

Add this somewhere in your htaccess:

RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /index\.php\?p=([^&]+)&o=(.+)\ HTTP
RewriteRule index.php /%2/%3 [R=301,L]

And if you want to cover the case where there's no "temporary_override", add this too:

RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /index\.php\?p=(.+)\ HTTP
RewriteRule index.php /%2 [R=301,L]

Closer, but I can't figure out how to get rid of the GET vars which are being added to the URL or why it's redirecting to the root directory instead of to the RewriteBase directory

Add a ? at the end of /%4/%5 to get rid of the query string. And remove the leading / from /%4/%5 to keep it from rewriting to the root. So, for example, one of your rules should look like this:

RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ \/([^\/]+\/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^index\.php$ %4/%5? [R=301,L]
终陌 2025-01-10 06:36:46

您将需要使用以下内容:

RewriteRule ^([^/]+)/?$ index.php?p=$1 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?p=$1&o=$2 [L,QSA]

这样,example.com/page_name 就会在内部传递给 index.php?p=page_nameexample。 com/page_name/operation 被传递到 index.php?p=page_name&o=operation。乔恩·林的回答似乎做了相反的事情,这是我昨晚没有注意到的。

除了为了避免与您可能拥有的其他规则发生冲突(只是为了澄清)之外,不需要任何 RewriteCond。

You're going to want to use the following:

RewriteRule ^([^/]+)/?$ index.php?p=$1 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?p=$1&o=$2 [L,QSA]

This way, example.com/page_name gets internally passed to index.php?p=page_name and example.com/page_name/operation gets passed to index.php?p=page_name&o=operation. Jon Lin's answer seems to have been doing the opposite, which I hadn't noticed last night.

There shouldn't be any need for any RewriteConds except to avoid conflict with other rules that you might have, just to clarify.

姐不稀罕 2025-01-10 06:36:46

您的 RewriteRule 行中的第 2 行更改应以 ? 结尾,如下所示:

#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^ /%4/%5? [R=301,L]

#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^ /%4? [R=301,L]

Change 2 of your RewriteRule lines should end with ? like this:

#if 2 GET Vars
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=([^&]+)&[op]=(.+)\ HTTP\/
RewriteRule ^ /%4/%5? [R=301,L]

#if 1 GET Var
RewriteCond %{THE_REQUEST} ^([A-Z]{3,9})\ /([^/]+/)*(index\.php)?\?[op]=(.+)\ HTTP\/
RewriteRule ^ /%4? [R=301,L]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文