RewriteCond Simple Issue - mod-rewrite

I need the URl http://mydomain.com/careers to go to http://mydomain.com/#!/careers
For what it's worth I've tried numerours variations around this with no success
RewriteCond %{REQUEST_URI} !^/careers$
RewriteRule (.*) /#!/careers [QSA,L]
Can anyone help?

"!" in your RewriteCond line means "not"...
Also, "[QSA,L]" means:
L means this is last rule (processing terminates after matching this one) and
QSA means query string append
But, becase R flag was not specified, this is done by sub-request and not a redirect, so the actual URL in your browser does not change...
Try this:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/careers$
RewriteRule (.*) /#!/careers [R,L,QSA]
Hope this helps

Related

Mod rewrite rule for mapping one or two parameters

I have the following .htaccess:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([^/]+)/?$ /?page=$1 [L,QSA]
RewriteRule ^/?([^/]+)/([^/]+)/?$ /?page=$1&id=$2 [L,QSA]
This rules allow to enter urls like:
example.com/my-account-dashboard
example.com/my-account-dashboard/1
which are pretty urls for:
example.com?page=my-account-dashboard
example.com?page=my-account-dashboard&id=1
This works fine so far. But internaly the links are with those parameters. Is it possible to redirect (or something) to the pretty urls if possible? What are the rewrite rules for that?
First of all, a few remarks about your current code which contains some errors.
1) RewriteCond only applies on the very next RewriteRule. So your second RewriteRule can match without that condition (you can try it, you'll see). You need to put (again) that condition to the other RewriteRule (or use S skip flag to simulate if/else condition but it gets complicated for nothing).
2) I'm pretty sure you don't want to use QSA flag the way you do. By using it, you tell mod_rewrite to append any query string to the rewrite. Example: example.com/my-account-dashboard/?foo=bar will rewrite to /?page=my-account-dashboard&foo=bar. So unless you really want that, you don't need it. A lot of people think that they need QSA when adding some query string directly in the rewrite, just like you do. Again, this is not an error that will make everything crash, but still it's not totally correct.
3) Your rules create duplicate content which is bad for SEO (referencing). For instance, example.com/my-account-dashboard and example.com/my-account-dashboard/ (notice the trailing slash) both lead to the same page. But search engines won't consider them as the same. I invite you to search "duplicate content" on Google (or any other search engine you like) and have a look at it. A simple way to avoid this is to chose either with or without the trailing slash.
Now that the base is clear, let's answer to your question. You can't simply use a redirect R from old-url to new-url because you'd end up with an infinite loop. Something is there for this problem: THE_REQUEST. When mod_rewrite uses it, it is able to know that it comes from a direct client request, not a redirect/rewrite by itself.
All-in-one, here is how your code should look like:
RewriteEngine On
RewriteBase /
# Redirect old-url /?page=XXX to new-url equivalent /XXX
RewriteCond %{THE_REQUEST} \s/\?page=([^/&\s]+)\s [NC]
RewriteRule ^ /%1? [R=301,L]
# Redirect old-url /?page=XXX&id=YYY to new-url equivalent /XXX/YYY
RewriteCond %{THE_REQUEST} \s/\?page=([^/&\s]+)&id=([0-9]+)\s [NC]
RewriteRule ^ /%1/%2? [R=301,L]
# if /XXX is not a file/directory then rewrite to /?page=XXX
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([^/]+)$ /?page=$1 [L]
# if /XXX/YYY is not a file/directory then rewrite to /?page=XXX&id=YYY
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([^/]+)/([0-9]+)$ /?page=$1&id=$2 [L]
NB: i chose to use the "without trailing slash" option (e.g. example.com/my-account-dashboard and example.com/my-account-dashboard/1). Feel free to ask if you want with.

Relative path and mod_rewrite issue

Have a trouble with mod_rewrite.
I want :
htp://example.com/a/some_text -> htp://example.com/?p1=some_text and
htp://example.com/b/some_text -> htp://example.com/?p1=some_text
So, I type:
RewriteCond %{REQUEST_URI} ^(.*)\/(a|b)\/(.*)$
RewriteRule ^(.*)$ ?fsearch=$2 [QSA]
and get wrong relative paths in css, such as htp://example.com/a/CSS/main.css instead of htp://example.com/CSS/main.css. And get nothing in $2 too.
Help, please
$2 tries to pick the second capture group of the RewriteRules subject, but there is only one! You probably mean %2 which picks from the RewriteCond...
Since you only append a query string in your RewriteRule the original URI (path) is left untouched.
You can simplify the pattern in the RewriteRule since you are not interested in the subject anyway.
This is probably what you are looking for:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^(.*)\/(a|b)\/(.*)$
RewriteRule ^ /?fsearch=%3 [QSA]
Much better however would be to rewrite directly to whatever script you actually want to process the request to safe another rewriting round to find the index document, so something like:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^(.*)\/(a|b)\/(.*)$
RewriteRule ^ /index.php?fsearch=%3 [QSA]
And unless you decide to use the first capture group in the RewriteCond you can also simplify that further:
RewriteEngine on
RewriteCond %{REQUEST_URI} \/(a|b)\/(.*)$
RewriteRule ^ /index.php?fsearch=%2 [QSA]

mod_rewrite with trailing period in URL

I have a RewriteRule on my Apache to make URLs friendly
RewriteRule ^log/(.+)$ script.php?u=$1 [QSA]
This makes http://example.com/log/username get internally redirected to http://example.com/script.php?u=username
This works fine, as long as the username does not contain a trailing period. However, there are usernames, where people chose names like "firstname-L." (note the trailing period)
In this case http://example.com/firstname-L. gets translated to http://example.com/script.php?u=firstname-L (the trailing period is gone)
How can I get this to work?
You can try to check these configuration directives:
RewriteCond %{REQUEST_URI} !^/log/(.+)\.$
RewriteRule ^log/(.+)$ /script.php?u=$1 [QSA]
RewriteCond %{REQUEST_URI} ^/log/(.+)\.$
RewriteRule ^log/(.+)$ /script.php?u=$1. [QSA]
OR:
RewriteCond %{REQUEST_URI} ^/log/(.+)([a-zA-Z0-9_-]{1})$
RewriteRule ^log/(.+)$ /script.php?u=$1 [QSA]
RewriteCond %{REQUEST_URI} ^/log/(.+)\.$
RewriteRule ^log/(.+)$ /script.php?u=$1. [QSA]
I hope, I'm not mistaken.. Now, as the variable of usernames with one character or one character with trailing period won't work in the second code, we can try to replace the second code with this one:
RewriteCond %{REQUEST_URI} ^/log/(.*)([a-zA-Z0-9_-]{1})$
RewriteRule ^log/(.+)$ /script.php?u=$1 [QSA]
RewriteCond %{REQUEST_URI} ^/log/(.*)\.$
RewriteRule ^log/(.*)$ /script.php?u=$1. [QSA]
Or you could try these three liner directives if you doesn't like the four liner:
RewriteCond %{REQUEST_URI} ^/log/(.*)\.$
RewriteRule ^log/(.*)$ /script.php?u=$1. [QSA]
RewriteRule ^log/(.*)([a-zA-Z0-9_-]{1})$ /script.php?u=$1$2 [QSA]
I hope, all these codes above will work!
Your rule appears to be right, perhaps the client or server is stripping the last dot as spurious (checked on YT with Chrome, if you add a dot at the end of a video url (?=xxxxxxxxx to ?=xxxxxxxxx.) and press enter, it gets removed -- actually triggering a 303 HTTP response).
In general, you should use only upper/lowercase letters and non-trailing dashes or dots in urls to compose the so-called slug, which is guaranteed to be handled correctly across all decent browsers and web servers.

Mod rewrite redirection to another domain if file not exist

What I'm trying to do:
I need to redirect a request to a file to another domain if the file not exists. For example:
http://www.mydomain.com/js/foo.js
redirects to (if not exists)
http://www.myanotherdomain.com/js/foo.js
What I do:
I wrote the next lines at the end the htaccess, but they redirect ALL!
RewriteCond %{REQUEST_URI} !-f
RewriteRule ^(.*)$ http://www.myanotherdomain.com/$1 [L,NC]
Before these lines, I have a lot of lines like this (I'm using MVC (Model, View,Controller)):
RewriteRule ^car/brand/?$ ?controller=Car&action=viewBrand [L,NC]
What happens:
It works wells with non existing files, but seems to be imcompatible with the MVC rules. These rules have to match and then stop evaluating rules because de "L" flag. But it seems to continue evaluation of the rules and finally evaluates the redirect rule. The result is this:
http://www.mydomain.com/car/brand/
goes to
http://www.myanotherdomain.com/?controller=Car&action=viewBrand
Please can anyone help me?
Thank you very much,
Jonathan
Try this:
RewriteCond %{REQUEST_FILE} !-f
RewriteRule ^(.*)$ http://www.myanotherdomain.com/$1 [QSA,R,L]
See also: mod rewrite directory if file/folder not found
Try placing these rules after your MVC rules:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\.(js|png|jpe?g|gif|css|html?)$ http://www.myanotherdomain.com/$1.$2 [L,R,NC]
If you want all requests, and not just static content like scripts and images then change the RewriteRule line to:
RewriteRule ^(.*)$ http://www.myanotherdomain.com/$1 [L,R,NC]

RewriteCond variable back-referencing of %2

this is htaccess file on the server
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www.
RewriteCond %{HTTP_HOST} ^([a-z0-9]+)\.domain.com(.*)$
RewriteRule ^(.*)$ http://domain.com/test\.php?user=%1&path=%2 [R]
According to my understanding of the above code if i request asher.domain.com/user it should rewrite to http://domain.com/test.php?user=asher&path=/user right?
Instead i get http://domain.com/test.php?user=asher&path= The %2 is empty. but if i use $1 instead of %2 i seem to get the right result.
I might be doing the silliest mistake ever but I am not sure where I my mistake is. Help me out here guys? where is the mistake in the rewrite rules that %2 is not working for me?
Using the $ syntax gives you RewriteRule backreferences, while the % will give you RewriteCond backreferences. The mod_rewrite documentation covers this.
In your case, your RewriteRule should look like:
RewriteRule ^(.*)$ http://domain.com/test\.php?user=%1&path=$1 [R]
Because you want the first group match from the previous RewriteCond and the first group match from the current RewriteRule.

Resources