I have a very simple url rewriting rules:
RewriteEngine on
RewriteCond %{HTTP_HOST} !script.php
RewriteRule ^test/(.*) script.php?q=$1
The idea is to have this kind of urls: http://mywebsite.com/test/http://example.com
and then send http://example.com to the script.php as a query parameter. The problem is that I'm receiving http:/example.com instead of http://example.com. Also, http:////example.com would be sent as http:/example.com. What causes this behavior ?
Apache mod_rewrite engine converts multiple ///... into single / for pattern matching in RewriteRule directive. However if you match it using RewriteCond then you can match multiple /s.
You can use rule like this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/+test/+(https?://.+)$ [NC]
RewriteRule ^ script.php?q=%1 [L,QSA]
The browser causes this behaviour. It contracts a sequence of / into 1 /, because it is still essentially a path. ///// does not change the directory we are in, so we could as well use /.
You have two options:
Change your links to use a query string instead. If you rewrite test/?q=something to script.php?q=something everything works as expected. You would do the following:
RewriteRule ^test/?$ script.php [L]
Since you don't alter the query string, the original query string is automatically copied to the new query string.
Don't make an assumption on how many slashes you will encounter. The url might not look correctly in the url bar of the browser, but if it is just a redirect, it will only be visible for a very short period of time.
RewriteRule ^test/(http|https):/+(.*)$ script.php?q=$1://$2
Related
Using .htaccess, I'm trying to find out how to redirect any requests to my site base URL / domain but to allow any requests with query strings, and if possible, only certain prepended query strings. For example:
Request to / is redirected to blog.example.com/
Request to /?anything (even without =) will be served as usual
Bonus points if anyone can describe how all pages would be redirected unless only containing certain query strings.
You can use this rewrite rule:
RewriteEngine on
RewriteCond %{QUERY_STRING} ^$
RewriteRule ^/?$ https://blog.example.com/ [R=301,L]
The condition with %{QUERY_STRING} ^$ ensures that the query string is empty (starts with symbol followed by ends with symbol.)
The rule ensures that the path contains at most a single slash and causes the redirect.
If you want to redirect everything except a specific query string, you can use a very similar rule. This one will redirect any query string on the root path except /?foo=bar
RewriteEngine on
RewriteCond %{QUERY_STRING} !^foo=bar$
RewriteRule ^/?$ https://blog.example.com/ [R=301,L]
No matter how many rewrite rules you have, you only need one instance of RewriteEngine on in your .htaccess.
I am trying to redirect all invalid urls to my index.php file via my .htaccess file.
Unfortunately I keep getting an Apache error.
My .htaccess file
RewriteEngine on
RewriteCond %{REQUEST_URI} !\.(?:css|js|jpe?g|gif|png)$ [NC]
RewriteRule ^([a-zA-Z0-9\-\_\/]*)$ index.php?p=$1
RewriteRule ^([A-Za-z0-9\s]+)$ index.php?p=$1 [L]
This invalid url shoud redirect to index.php:
/vacatures/jobapplication/facility-manager%20qsdf
But it throws the object not found 404 Apache error.
The rule you have which allows spaces does not allow hyphens. The rule you have which allows hyphens does not allow spaces. So anything which includes both will not match either.
Your invalid URL facility-manager%20qsdf includes both.
My guess is that your RewriteCond is supposed to apply to both rules, but that is not what is happening now, it will apply only to the first RewriteRule after it. You can solve all these problems by including just 1 RewriteRule, and amending it to accept everything you want:
RewriteRule "^([A-Za-z0-9\-\_\/\s]+)$" index.php?p=$1 [L]
Note that this requires at least one of the characters in your character class, in other words it will not match your "home" location when there is no path ("http://somewhere.com/"). If you want to also match for that location, change the + to a *, to allow 0 or more character matches.
Your rewrite rules do not match the url you indicated. Your REQUEST_URI is
/vacatures/jobapplication/facility-manager%20qsdf
I suspect the URL decoding is not done before the RewriteRule matching and therefore it's trying to match literally %20, yet % sign is not included in your match. I'm not sure why you're using two RewriteRules - why not do something like this?
RewriteEngine on
RewriteCond %{REQUEST_URI} !\.(?:css|js|jpe?g|gif|png)$ [NC]
RewriteCond %{REQUEST_URI} !^index.php(\?.*)?$
RewriteRule ^(.*)$ index.php?p=$1 [L]
I'm trying to figure out how to rewrite urls using apache webserver and php.
The url below is the real nonrewritten url:
http://localhost:1337/rewritetest/index.php?id=12
And I want to reach it by
http://localhost:1337/rewritetest/index/12
My indexfile looks like this:
<?php
echo $_GET['id'];
?>
Is this possible? The "new" url doesn't include any parameter names so I guess I have to use an order of parameters instead but I dont know how to reach them in that case.
Below is as far I've come with my rewrite:
RewriteCond %{QUERY_STRING} id=([-a-zA-Z0-9_+]+)
RewriteRule ^/?index.php$ %1? [R=301,L]
RewriteRule ^/?([-a-zA-Z0-9_+]+)$ index.php?id=$1 [L]
Anyone have an idea of what I'm doing wrong?
it's located in the same folder as index.php
So, given the .htaccess file is located at /rewritetest/.htaccess (as opposed to the document root ie. /.htaccess) then...
RewriteRule ^/?([-a-zA-Z0-9_+]+)$ index.php?id=$1 [L]
If you request a URL of the form /rewritetest/index/12 then the above RewriteRule pattern won't actually match anything. It tries to match "index/12", but your pattern does not contain a slash so will fail. (Is the + inside the character class intentional?)
Try something like the following instead:
RewriteRule ^(index)/(\d+)$ $1.php?id=$2 [L]
This obviously specifically matches "index" in the URL. If you are always rewriting to index.php then you don't really need "index" in the URL - unless this means something different? This also assumes that the valuue of the id parameter consists only of digits.
To rewrite the more general .../<controller>/26 to .../<controller>.php?id=26 (as mentioned comments) then try something like:
RewriteRule ^([\w-]+)/(\d+)$ $1.php?id=$2 [L]
In per-directory .htaccess files the slash prefix is omitted on the URL-path that is matched by the RewriteRule pattern, so /? is not required. The above pattern also matches something for for the id, not anything. So, /index/ would not match.
If this is a new site then the "redirect" (from /index.php?id=12 back to /index/12) is not necessarily required. That's only really required if you are changing the URL structure on an existing site where old URLs already have inbound links and are indexed by search engines. In which case you could do something like the following before the internal rewrite:
RewriteBase /rewritetest/
RewriteRule %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^id=(\d+)
RewriteRule ^(index)\.php$ $1/%1 [R,L]
Or, for a more generic .../<controller>/26 to .../<controller>.php?id=26 (as above) then change the RewriteRule to:
RewriteRule ^([\w-]+)\.php$ $1/%1 [R,L]
The additional check against the REDIRECT_STATUS environment variable is to prevent a rewrite loop after having rewritten the URL to /index.php?id=12 earlier.
UPDATE: This works:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{THE_REQUEST} ^[A-Z]+\ ([^\s]+)
RewriteRule (.+) /index.cfm?event=checkuri&uri=%1 [QSA]
Some background...
So we already have a catchall redirect in our .htaccess file which is this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) /index.cfm?event=checkuri&uri=$1
This ties into a database table that checks the URI for a match. so if we just moved a site that used to have this page:
/some-awesome-article.html
Onto our system, and the new address is
/awesome-article/12442
and someone tried to access the old URI, our system would check for this, find a match, and forward them to the new home: /awesome-article/12442
This system works awesome, with one exception. If the URI is something like /index.php?id=123412 then the whole system falls apart. In fact /index.php/whatever won't work either.
Everything else works except for this. We do not use PHP for our web application (although support says its in an admin console on the server somewhere).
So basically what I need is if index.php is detected anywhere it will forward the URI to our
existing system:
How can i modify this to fix it?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) /index.cfm?event=checkuri&uri=$1
Try changing your code to:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.+) /index.cfm?event=checkuri&uri=$1 [L,QSA]
QSA is for Query String Append that will make sure to append existing query parameters with the new ones.
Rewriting with mod_rewrite does not work on the full URL. In fact, the regex in the RewriteRule does only get the path and file, but not the query string. And so the backreference $1 will only contain "index.php" and nothing else.
Additionally, the RewriteRule does change the query string because there is one in the target pattern. Because the flag [QSA] (query string append) is not present, the query string of the original request gets replaced instead of appended. So the query string is gone after this rewriting.
This would be a lot easier if you wouldn't mess with the query string. The easiest way of rewriting any url that is not an existing file would be if the second line would be simply RewriteRule (.+) /index.cfm - you could then get all info about the current request, including query string, path and file, in the script.
So now you'd have to fiddle with the query string. Adding [QSA] will pass the query string to your script and you'd have to detect what's inside. This will work only if you do not expect the query string to contain parameters named "event" and "uri" - these will be overwritten by your rewriting. If you need to add the original query string to the URL, it's a bit more complicated, because the string needs to be url-encoded.
Here's how to do that.
Based on your comments, it sounds like you need to use the Query String Append QSA flag on your rule like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.cfm?event=checkuri&uri=$1 [QSA,L]
In your example case the rewrite would look like:
/index.cfm?event=checkuri&uri=index.php&id=123412
Sven was very close so I'm giving him the check
This ended up working perfectly:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{THE_REQUEST} ^[A-Z]+\ ([^\s]+)
RewriteRule (.+) /index.cfm?event=checkuri&uri=%1 [QSA]
My directories are like:
http://www.mydomain.com/macbook-computer
http://www.mydomain.com/sony-computer
http://www.mydomain.com/lenovo-computer
I want to make that, if a user type computers/macbook-computer like:
http://www.mydomain.com/computers/macbook-computer
I want to display page which is : http://www.mydomain.com/macbook-computer.
My restrictions are:
1. User must type /computers (segment 1)
2. String coming from computers/ must end with "computer". (segment 2)
How can I make this achieve in my .htaccess file?
You may try this:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/computers/([^-]+)-computer/? [NC]
RewriteRule .* %1-computer? [R=301,L]
Redirects permanently
http://www.mydomain.com/computers/anyname-computer with or without trailing slash.
To:
http://www.mydomain.com/anyname-computer
Strings computers and computer are assumed to be fixed, while anything is assumed to be variable.
The incoming URL structure has to be kept for the rule-set to work: First folder /computers followed by /anyname-computer.
For silent mapping, remove R=301 from [R=301,L]
You need a rewrite rule in your .htaccess file, and a little regular expression magic. Something like this should do the trick
RewriteRule ^computers/macbook-computer$ http://www.mydomain.com/macbook-computer
Here's a nice online tool for checking rewrite rules
http://htaccess.madewithlove.be/