问题
I am trying to both rewrite and redirect this URL:
https://www.domain.com/video-lessons-page.php?item=stocks
to go to this URL:
https://www.domain.com/stocks-video-lessons
Here is the code I'm currently working with:
RewriteCond %{QUERY_STRING} ^item=([^&]+)
RewriteRule ^/?video-lessons-page\.php$ https://www.domain.com/%1-video-lessons? [R=301,L]
RewriteRule ^(stocks|finance|accounting)-video-lessons$ video-lessons-page.php?item=$1 [NC,L]
Unfortunately with the above code I'm having issues. The first two lines work great by themselves in that it redirects /video-lessons-page.php?item=stocks
to /stocks-video-lessons
.
And the third line also works great by itself to where the /stocks-video-lessons
URL functions correctly with the GET variable and the page's code.
But putting them together is problematic. Right now I'm getting errors like "www.domain.com redirected you too many times." etc. Any ideas?
回答1:
Just to clarify, presumably you have already changed all your internal URLs to the form /stocks-video-lessons
and the reason for the external redirect is because the "ugly" URLs have already been indexed and linked externally?
As you have found, you are getting a redirect loop because these two rules conflict and it's constantly redirecting/rewriting from one to the other.
You need to redirect when only the initial request contains the URL /video-lessons-page.php
, not the rewritten URL (which is what's happening here). You can check the initial request by checking against THE_REQUEST
server variable (which contains the full HTTP request as sent by the browser).
Something like the following:
RewriteCond %{THE_REQUEST} /video-lessons-page\.php?item=(\w+)
RewriteRule ^video-lessons-page\.php$ https://www.example.com/%1-video-lessons? [R=301,L]
RewriteRule ^(stocks|finance|accounting)-video-lessons$ video-lessons-page.php?item=$1 [L]
Note you must clear your browser cache before testing, since 301 (permanent) redirects will be cached by the browser. (Often easier to test with 302 redirects.) Only use the NC
flag if you specifically need a case-insensitive match.
UPDATE: I've changed the regex on the query string parameter value, from ([^&]+
) to the slightly more restrictive (\w+
). \w
being the shorthand character class for a word character (which naturally excludes &
and crucially spaces). Since THE_REQUEST
contains a string of the form:
GET /video-lessons-page.php?item=stocks HTTP/1.1
...we need to stop capturing before the space. The previous pattern ([^&]+)
would have captured everything to the end of the string ie. "stocks HTTP/1.1". So, I would have expected a 404, since an invalid redirect would have occurred but the internal rewrite would have failed. (?)
回答2:
Thanks to w3dk's guidance, I figured it out, just needed a QUERY_STRING
to stay in place in addition to the THE_REQUEST
.
Final code:
RewriteCond %{THE_REQUEST} video-lessons-page\.php
RewriteCond %{QUERY_STRING} ^item=([^&]+)
RewriteRule ^video-lessons-page\.php$ https://www.example.com/%1-video-lessons? [R=301,L]
RewriteRule ^(stocks|finance|accounting)-video-lessons$ video-lessons-page.php?item=$1 [L]
来源:https://stackoverflow.com/questions/38862491/htaccess-rewrite-and-redirect-url-with-php-get-variable