Why won't my RewriteRules play nice together? - .htaccess

The first part of my code works and redirects/rewrites to new/file. Problem occurs when I try to pass variables. They all get redirected to new/file
Whatever variable I try to pass in file.php?foo=bar redirects to new/file instead of new/file/bar.
for example:
new/file rewrites to file.php
new/file/2 rewrites to file.php?page=2
file.php redirects to new/file
file.php?page=2 doesn't redirect to new/file/2 but get's overwritten to new/file instead
My code:
RewriteBase /domain.com
#regular
RewriteCond %{QUERY_STRING} !redirect=no
RewriteRule ^file\.php$ new/file? [NS,R=301,L]
RewriteRule ^new/file?$ file.php?redirect=no [NS]
#with variable
RewriteCond %{QUERY_STRING} ^page=([0-9-]+)/?$
RewriteRule ^file\.php$ new/file/%1? [NS,R=301,L]
RewriteRule ^new/file/([0-9-]+)/?$ file.php?page=$1&redirect=no [NS]
Please note that I am passing more than just page variables.
I'm thinking maybe a QSA flag is supposed to go somewhere?

RewriteCond %{QUERY_STRING} !redirect=no
RewriteRule ^file\.php$ new/file [NS,R=301,L]
RewriteRule ^new/file$ file.php?redirect=no [NS]
In line 2 you had ?. This will replace the current querystring, and page=2 is lost.
In line 3 you had a ?. Paths don't contain questionmarks. Secondly the questionmark is interpreted as an "optional letter 'e'", because it is a RegEx. So "/new/fil" would also work (try it out).

Related

add string at the end of URL using htaccess which has query string also

I want to change
domain.com/division1/index.php?members/maxmusterman.5
to
domain.com/division1/index.php?members/maxmusterman.5/#div
That is if the URL contains index.php?members, then I add /#div at the end of url. I tried this
RewriteEngine On
RewriteCond %{REQUEST_URI} index.php?
RewriteRule (.*) /%1/%{QUERY_STRING}&123 [L,QSA,R=301]
but it returns
domain.com/members/maxmusterman.5&123?members/maxmusterman.5
Note here that &123 is attached after URI before starting parameters. I researched htaccess QSA flag but I could not find a way to add a custom string at the end of the query string. How can I do that. Here I have used &123 for test purpose, actual requirement is adding /#div
To redirect
domain.com/division1/index.php?members/maxmusterman.5
to
domain.com/division1/index.php?members/maxmusterman.5/#div
.
You can use something like the following :
RewriteEngine on
RewriteCond %{QUERY_STRING} !loop=no
RewriteRule ^division1/index\.php$ %{REQUEST_URI}?%{QUERY_STRING}&loop=no#div [L,R,NE]
I added an additional perameter loop=no to the destination url to prevent infinite loop error .You can't avoid this as both your old url and the new url are identical and can cause redirect loop if you remove the RewriteCond and Query perameter.
NE (no escape ) flag is important whenever you are redirecting to a fragment otherwise mod-rewrite converts the # to its hex %23 .
solution #2
RewriteEngine on
RewriteCond %{THE_REQUEST} !.*loop=no [NC]
RewriteCond %{THE_REQUEST} /division1/index\.php\?(.+)\s [NC]
RewriteRule ^ /division1/index.php?%1&loop=no#div [NE,L,R]
Clear your browser cache before testing these redirects.

Using mod rewrite to redirect, using query string value with characters replaced

I have old URLs like this:
http://www.foo.org/cgi-bin/search.cgi?Blog=14&tag=my%20long%20tag%20name&limit=100
which I want to redirect to another server's page like:
http://www.bar.org/tag/my-long-tag-name/
On foo.org I have:
RewriteCond %{QUERY_STRING} ^Blog=14&tag=([^&]*)&.*$ [NC]
RewriteRule ^cgi-bin/search.cgi$ http://www.bar.org/tag/%1/? [NC,R=301,L]
This redirects to the correct page on bar.org, where I need to replace the %20s with hyphens. However, it changes every %20 to %2520. I've tried adding the NE flag, but no change. This is the thing I'm stuck with.
Once there, this rule replaces %20s with hyphens:
RewriteRule ^blog/tag/([^\s]*)(?:\s)+(.*)/$ /blog/tag/$1-$2/ [R=301,L]
(Bonus points... some of those original tag values also have %28 and %29 in them, which ultimately I'd like to delete. So a tag of bob%20and%20%28thelma%29 becomes bob-and-thelma.)
You can use these rules in site root .htaccess of www.foo.org:
RewriteEngine On
# temporary rewrite to /tag/tag-name
RewriteCond %{QUERY_STRING} ^Blog=14&tag=([^&]*) [NC]
RewriteRule ^cgi-bin/search\.cgi$ /tag/%1? [L]
# redirect to http://www.bar.org if there is no special char in URI
RewriteRule ^tag/[^\x20\x28\x29]+$ http://www.bar.org/$0 [NC,L,NE,R=301]
# if special char is in the end then simple remove it
RewriteRule ^(tag)/([^\x20\x28\x29]*)[\x20\x28\x29]+$ $1/$2 [NC,N,DPI]
# otherwise replace special char by a hyphen
RewriteRule ^(tag)/([^\x20\x28\x29]*)[\x20\x28\x29]+(.+)$ $1/$2-$3 [NC,N,DPI]

mod_rewrite and redirect causing loop

I have problem when I try to redirect and rewrite together.
I have site example.com/show_table.php?table=12 (max 99 tables). I wanted nice links, so I got this .htacces rw rule:
RewriteRule ^table/([0-9]{1,2})$ show_table.php?table=$1 [L,NC]
Now are links something like example.com/table/12 - it's definitely OK. But I want all old links redirect to new format. So I use Redirect 301, I added to .htaccess this code:
RewriteCond %{REQUEST_URI} show_table.php
RewriteCond %{QUERY_STRING} ^table=([0-9]{1,2})$
RewriteRule ^show_table\.php$ http://example.com/table/%1? [L,R=301,NC]
But when I visit example.com/show_table.php?table=12, I receive just redir-loop. I don't understant - the first is rewrite, the second is redirection, there ain't no two redirections. Do You see any error?
Thanks!
Instead of checking REQUEST_URI in the condition, you need to be checking in THE_REQUEST (which contains the full original HTTP request, like GET /show_table.php HTTP/1.1). When Apache performs the rewrite, it changes REQUEST_URI, so to the rewritten value, and that sends you into a loop.
# Match show_table.php in the input request
RewriteCond %{THE_REQUEST} /show_table\.php
RewriteCond %{QUERY_STRING} ^table=([0-9]{1,2})$
# Do a full redirection to the new URL
RewriteRule ^show_table\.php$ http://example.com/table/%1? [L,R=301,NC]
# Then apply the internal rewrite as you already have working
RewriteRule ^table/([0-9]{1,2})$ show_table.php?table=$1 [L,NC]
You could get more specific in the %{THE_REQUEST} condition, but it should be sufficient and not harmful to use show_table\.php as the expression.
You'll want to read over the notes on THE_REQUEST over at Apache's RewriteCond documentation.
Note: Technically, you can capture the query string in the same RewriteCond and reduce it to just one condition. This is a little shorter:
# THE_REQUEST will include the query string so you can get it here.
RewriteCond %{THE_REQUEST} /show_table\.php\?table=([0-9]{1,2})
RewriteRule ^show_table\.php$ http://example.com/table/%1? [L,R=301,NC]

.htaccess redirect with ignore query string

I would like to redirect without looking at the query string, and my redirect result no need append the query string as well, so I add a ? at the end of the RewriteRule.
I tried the following syntax, but the outcome just close to it.
RewriteCond %{QUERY_STRING} .* [NC]
RewriteRule ^exd\.asp$ http://www.example.com/index.php?r=p/consumer? [R=301,L]
and also, i tried to escape the first ?, which I need it, but still the same outcome.
RewriteRule ^exd\.asp$ http://www.example.com/index.php\?r=p/consumer? [R=301,L]
Outcome:
http://www.example.com/index.php?r=p/consumer%3f
I want to get ride of the %3f.
Thanks!
You don't need to append a ? at the end if you already have a query string in your target. Just do this:
RewriteCond %{QUERY_STRING} .* [NC]
RewriteRule ^exd\.asp$ http://www.example.com/index.php?r=p/consumer [R=301,L]
By default, query strings get appended, like this:
RewriteRule ^foo$ /bar [L]
You request /foo?blah and you get /bar?blah
However, if you have a ? in your target, query strings won't get appended unless you have the QSA, so:
RewriteRule ^foo1$ /bar? [L]
RewriteRule ^foo2$ /bar?q=2 [L]
You request /foo1?blah and you get /bar, you request /foo2?blah and you get /bar?q=2. If you include a QSA in the rewrite flags, then &blah gets appended to the end.

Why is my pagination not working after mod rewrite?

Before rewriting my url file.php?style=foo&page=2 works fine.
After rewrite it stops working and just stays on the same page with the ?page variable at the end like it's not getting caught:
foo-new?page=2
After the rewrite the page parameter stops working on the clean url.
Here's what my rewrite rules look like:
RewriteCond %{QUERY_STRING} ^style=([A-Za-z-]+)/?$
RewriteRule ^file\.php$ %1-new? [NS,R=301,L]
RewriteRule ^([A-Za-z-]+)-new/?$ file.php?style=$1&redirect=no [NS]
So I translate what you'd like to do then, I change your rules and write them. Please tell me if I'm right or wrong.
You'd like to check if in the query string you have an optional parameter "style".
RewriteCond %{QUERY_STRING} ^style=([A-Za-z-]+)/?$
What is the point of the ^ and the /? and the $ ? Remove them:
RewriteCond %{QUERY_STRING} style=([A-Za-z-]+)
It's clearer this way and should still work for what you want.
RewriteRule ^file\.php$ %1-new? [NS,R=301,L]
What is the point of the ? ? Remove it:
RewriteRule ^file\.php$ %1-new [NS,R=301,L]
So, please try these rules and tell me if they work, and if not, please be more specific or give real URL sample that you'd like to rewrite:
RewriteCond %{QUERY_STRING} style=([A-Za-z-]+)$
RewriteRule ^file\.php$ %1-new [QSA,NS,R=301,L]
RewriteRule ^([A-Za-z-]+)-new/$ file.php?style=$1&redirect=no [NS]

Resources