I'm close, to my final solution I think.
The .htaccess looks like this:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /myproject/development/
RewriteRule ^((?!index\.php)[^/]+)/?$ index.php?page=$1 [L]
RewriteRule ^((?!index\.php)[^/]+)/([A-Za-z0-9]+)/([0-9]+)/([0-9]+)/?$ index.php?page=$1&keyword=$2&zip=$3&range=$4 [L,R]
I don't need the RewriteBase for the 1st rule(was a little surprised about that) but I need it if I add the 2nd rule and open this URL:
//localhost/myproject/development/somepage/test/13245/50
Otherwise the page will be opened but of course without the stylesheets and javaScripts can be found then.
1.) Target: I want to use the 2nd rewriteRule without changing or adding a rewriteBase. What do I need to change in the .htaccess so I can keep testing my project without a rewriteBase.
Why: As I asked before I want to test my project locally and on the live-server without changing too much on the project configuration.
2.) The [R] Flag If I request
//localhost/myproject/development/somepage/test/53229/2000
Of course in the adressline then we have this URL
//localhost/myproject/development/index.php?page=somepage&keyword=test&zip=12345&range=2000
To avoid this behaviour I simply should remove the R-Flag. But then the CSS and JS can't be found anymore. Also Here I'm looking for a solution without rewritebase, basepath, virtual host, etc. if possible.
Here is where I started:
Rewrite rules for localhost AND live envoirement
By the looks, you don't want the R flag on the 2nd RewriteRule. That defeats the object of your "pretty" URLs.
But then the CSS and JS can't be found anymore.
Because you are using relative paths to your CSS and JS files. Either change your paths to root-relative (starting with a slash), or use the base element in the head section of your pages, to indicate the URL that all relative URLs are relative to:
<base href="http://www.example.com/page.html">
More Information:
https://developer.mozilla.org/en/docs/Web/HTML/Element/base
I don't need the RewriteBase for the 1st rule(was a little surprised about that)
You don't need the RewriteBase for the 1st rule (an internal rewrite) because the directory-prefix (the filesystem path that lead to this .htaccess file) is automatically added back on relative path substitutions.
However, for external redirects (ie. R flag), the directory-prefix does not make sense, so you either need to specify a root-relative (starting with a slash) or absolute URL. Or specify the appropriate RewriteBase directive, which overrides what URL-path will be added for relative substitutions (that's all it does).
Related
We have had our Website running on an older Apache2 instance with a large .htaccess file for redirects of old URLs to new ones. Since we have a lot of equal sub-URLs the redirect looks like this:
RewriteRule ^(.*)old/url(.*)$ new/url [L,R=301]
This worked like a charm.
For example www.example.com/a/old/url got redirected to www.example.com/a/new/url and also worked for /b/ or /c/.
With the new Apache (2.4.54) the redirect doesn't work as expected since it redirects as follows:
www.example.com/var/www/html/new/url
What am I doing wrong? Why does it place the base path of the website in front?
I've tried to google as good as possible but couldn't find anything. I would expect any weird path that I don't know of is set in the wrong way.
I'm not very deep into .htaccess which makes it hard to troubleshoot.
RewriteRule ^(.*)old/url(.*)$ new/url [L,R=301]
This worked like a charm.
For example www.example.com/a/old/url got redirected to www.example.com/a/new/url and also worked for /b/ or /c/.
It would only do that if you also had a RewriteBase /a directive defined elsewhere in the config file. (Although it's not clear how it would work the same for /b/ or /c/, unless you have other directives that are helping. Unless you mean that it redirects from /b/ or /c/ to /a/? In which case, the RewriteBase directive alone is what is enabling this to work.)
With the new Apache (2.4.54) the redirect doesn't work as expected since it redirects as follows: www.example.com/var/www/html/new/url
That will happen if RewriteBase is not defined as mentioned above.
This applies to both Apache 2.2 and 2.4.
However, it's also possible that RewriteBase is/was defined in a parent config and RewriteOptions MergeBase was set (which propagates the setting to child configs). A further complication is that in later versions of Apache 2.2 (specifically 2.2.23 and later) and early versions of Apache 2.4 (specifically 2.4.0 to 2.4.3) this was actually the default (arguably buggy) behavior. So, if you are upgrading from one of these "buggy" versions of Apache, it's possible this was "just working".
The RewriteBase directive defines the URL-path that is prefixed to relative substitution strings (new/url is a relative substitution string). If no RewriteBase is defined then the directory-prefix (ie. the absolute file-path of where the .htaccess file is located) is added back - which is resulting in your malformed redirect.
For external "redirects" it is often preferable to use a root-relative (starting with a slash) or absolute (scheme + hostname) substitution string. For example:
RewriteRule ^(.*)old/url(.*)$ /a/new/url [L,R=301]
The above is no longer dependent on the RewriteBase directive, since the substitution string (ie. /a/new/url) is no longer relative.
However, ^(.*)old/url(.*)$ is the same as simply old/url, which is rather too general. Perhaps something like the following would be preferable:
RewriteRule ^(a|b|c)/old/url /a/new/url [L,R=301]
The above redirects /a/old/url or /b/old/url or /c/old/url<anything> to /a/new/url.
OR, redirect to the same URL-path (ie. a, b or c) using a backreference:
RewriteRule ^(a|b|c)/old/url /$1/new/url [L,R=301]
You will need to clear your browser cache before testing, since the erroneous 301 (permanent) redirect will have been cached by the browser (and possibly any intermediary caches). Test first with 302 (temporary) redirects to avoid potential caching issues.
Reference:
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewritebase
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html#rewriteoptions
https://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriteoptions
So Ive been making a code which replaces one image with another without changing the link.
So heres the code that I found on one of the forums.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^.*/fredShip1.png$ /fredShip2.png [L]
</IfModule>
So this code not only redirects user to another page but also to a random link.
So original link is http://toss.rf.gd/storage/fredShip1.png though it should have replaced the image with http://toss.rf.gd/storage/fredShip2.png(Just an example) but it sends the user here toss.rf.gd/home/vol8_1/[Account info]/htdocs/storage/FredShip2.png
I added the image too ->
The image
I am really bad at htaccess so make sure correct me if Im wrong. Also english is not my first language so expect some minor mistakes.
EDIT : So i solved the problem with redirection to a random link. But Im still wondering is it possible to just change the image without changing the link?
RewriteRule ^.*/fredShip1.png$ /fredShip2.png [L]
The code you've posted already does essentially what you require, except that you need to adjust the paths to match your example. The "problem" with the above rule is that it rewrites the request to /fredShip2.png (in the document root), not /storage/fredShip2.png as in your example.
Assuming the .htaccess file is in the document root of the site and you wish to internally rewrite the request from /storage/fredShip1.png to /storage/fredShip2.png then you would do it like this:
RewriteRule ^storage/fredShip1.png$ storage/fredShip2.png [L]
There should be no slash prefix on the URL-path in either argument.
If you have other directives in your .htaccess file then the order of these directives can be important.
Make sure you've cleared your browser cache before testing.
but it sends the user here example.com/home/vol8_1/[Account info]/htdocs/storage/FredShip2.png
That's not possible with the directive you've posted. This is most likely a cached redirect due to an earlier (erroneous) experiment with 301 (permanent) redirects. For example, something like the following would produce the above "erroneous" output:
RewriteRule fredShip1\.png$ storage/FredShip2.png [R=302,L]
Note the use of the R (redirect) flag and the lack of a slash prefix on the RewriteRule substitution string (2nd argument). Since the substitution string is "relative", the directory-prefix (ie. /home/vol8_1/[Account info]/htdocs/ in your example) is prepended to substitution and since this is an external redirect (as denoted by the R flag) this then exposes the absolute filesystem path to the user.
NB: The above is a 302 (temporary) redirect - so should not be cached by the browser (at least not by default).
For some reason, I'm getting duplicate directory names in some urls within a subfolder on our website. This seems to affect only crawlers as the files within this directory work fine when navigated.
I'd like to simply remove the duplicate directory name and make mydomain.com/sub/sub redirect to mydomain.com/sub.
I've tried many versions but my .htaccess skills are lacking apparently. I currently have (not working of course):
RewriteRule ^mydomain.com/sub/sub/(.*) mydomain.com/sub/$1 [L,R=301]
RewriteRule ^mydomain.com/sub/sub/(.*) mydomain.com/sub/$1 [L,R=301]
The RewriteRule pattern matches against the URL-path only - you appear to have included (part of) the domain name. Also, mydomain.com in the substitution string is going to be seen as a relative subdirectory.
Assuming you have a limited number of subdirectories where this occurs then to reduce /sub/sub/<something> to just /sub/<something> you would do something like this:
RewriteEngine On
RewriteRule ^sub/sub/(.*) /sub/$1 [R=301,L]
If you have other directives in you .htaccess file, then this needs to go near the top.
First test with 302 (temporary) redirects to avoid potential caching issues. Clear your browser cache before testing.
But to echo #arkascha's comment... the reason why crawlers are finding these URLs in the first place would seem to be a fault in your URL structure/internal links - so this is what ultimately needs to be fixed.
I want to add rewriterules that works in local environment (localhost) and on my liveserver.
Why?
I don't want to change rules when I test my project locally and upload it to the liveserver.
Adding Rules
Here an example
(ANY-URL)index.php?page=somepage
change to
(ANY-URL)/somepage
So I used a rewritemod generator and pasted this into it:
index.php?page=somepage
The rewriterule I got, looks like this: (of course my .htacces starts with RewriteEngine On)
RewriteRule ^([^/]*)$ /?page=$1 [L]
When I try to get to (http:)
//localhost/myproject/development/index.php?page=login it sends me to the root directory of my local development envirment. But the URL in the adressline doesn't change.
Testing
Of course I tried some other Rules by pasting the whole URL into the generator just to test if the rewrite thing works.
Also here the URL doesn't change to short-url but the server cant find stylesheets and javascripts anymore. I got redirected to the index.php
Possible solutions?
Maybe it has something todo with that "RewriteBase"?
Do i have to set a basepath?
My .htacces is located here:
//localhost/myproject/development/.htaccess
Later I also want to change paths that look like this:
(ANY-URL)index.php?page=somepage&second=hello&third=world&fourth=cool
Also here a I'm looking for a solution that works on both environments.
Since the htaccess is located inside a sub-directory, use RewriteBase:
RewriteEngine On
RewriteBase /myproject/development/
Once that is done, you use the base element in your php/html files. This will resolve the addresses for the scripts/stylesheets in your pages.
<base href="/myproject/development/" />
Now, the rewrites in htaccess would be:
RewriteRule ^((?!index\.php)[^/]+)/?$ index.php?page=$1 [L]
This is a strange one...
A while back I managed to write a .htaccess redirect that worked so that the URL was read like: www.website.com/mt?page=index - and what the real URL of this page was www.website.com/PageParser.php?file=index.php
The problem has been that the FTP system of my webhost hides .htaccess files even though they are allowed and do operate - and so I have checked back on local copies I have of my .htaccess files and none of them have the code as to how this works - and I've forgotten how I did it!!
Essentially, I am using wildcards so that anything after mt?page= will actually be showing PageParser.php?file= but without having the PageParser.php showing within the URL (and this is the important bit, because the index.php on my site root is actually sent through PageParser.php first so that anything which shouldn't be there is wiped out before the end user sees it) - so how can .htaccess redirect/rewrite the URL so that any link to /mt?page= show the file located at /PageParser.php?file= without changing the URL the user sees?
RewriteEngine On
RewriteRule ^(.*)mt?page=(.*)$ $1PageParser.php?file=$2
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} ^page=([^&]+)
RewriteRule ^mt$ /PageParser.php?file=%1.php [NC,L]
This rule will rewrite (internal redirect) request for /mt?page=hello to /PageParser.php?file=hello.php without changing URL in browser.
Your source URL example (www.website.com/mt?page=index) has index while target URL (www.website.com/PageParser.php?file=index.php) has index.php. The above rule will add .php to the page name value, so if you request /mt?page=hello.php it will be rewritten to /PageParser.php?file=hello.php.php.
If there is a typo in your URL example and page value should be passed as is, then remove .php bit from rewrite rule.
The rule will work fine even if some other parameters are present (e.g. /mt?page=hello&name=Pinky) but those extra parameters will not be passed to rewritten URL. If needed -- add QSA flag to rewrite rule.
This rule is to be placed in .htaccess in website root folder. If placed elsewhere some small tweaking may be required.
P.S.
Better write no explanation (I knew it/I did it before .. but now I forgot how I did it) than having these "excuses". While it may be 100% true, it just does not sound that great.