Forum Moderators: phranque

Message Too Old, No Replies

RewriteRule in htaccess Issue

         

dcdeveloper

2:17 pm on Apr 18, 2010 (gmt 0)

10+ Year Member



I have been looking for quite a lot of posts on this forum in regards to the problem that I am currently having and it doesn't seem to get my head around.

basically my problem is I have this original URL:

www.mywebsite.com/sub/index.php?option=com_user&view=login&return=aHR0cDovL3d=

and I have been trying to rewrite the URL into something like the following:

www.mywebsite.com/sub/workflow

my .htaccess code looks like this:

Options +FollowSymlinks
RewriteEngine On
RewriteBase /sub
RewriteRule ^workflow$ index.php?option=com_user&view=login&return=aHR0cDovL3d=

when I type in the re-written URL, i.e. www.mywebsite.com/sub/workflow, on the browser
the result that is displayed is somehow not correct, unless on the re-written URL itself I added the querystring part then it will display the correct page.

Is there something wrong with my .htaccess code? Thanks in advance for your help.

jdMorgan

3:35 pm on Apr 18, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



First some clarification: The path that you are rewriting to is not a URL, it is a local server filepath. Further, it is more accurate to call example.com/sub/workflow "the URL to be rewritten," while index.php?option=com_user&view=login&return=aHR0cDovL3d is the "rewritten filepath" after this rule is invoked.

Sticking with the proper terms here may make the problem (or at least the responses you get here) easier to understand.

So this rule rewrites *from* the client-requested URL-path example.com/sub/workflow *to* the server local filepath /sub/index.php?option=com_user&view=login&return=aHR0cDovL3d

Note that I removed the trailing "=" in the following discussion and code, as it seems to have no "name" or "value" associated with it.

I don't see anything blatantly 'wrong' with this code, but there are several 'red flags' that may indicate errors.

First, you should not be needing to use RewriteBase here, unless *all* requests to this server are aliased by the server configuration to resolve to the "/sub" subdirectory.

Second, you have no [L] flag on the end of this rule, meaning that any subsequent rules will also be processed after this rule executes, possibly further changing the target path, corrupting it (due to a knowm Apache mod_rewrite bug), or even changing it to an external client redirect, exposing your filepath as a URL in the process -- with bad effect on your search results listings.

Problems may also accrue if you don't have [L] flags on rules preceding this one, or if any of your rules are not in the correct order. Generally, you want all redirects first, in order from most-specific patterns and conditions (affecting the fewest requested URLs) to least-specific patterns and conditions (affecting more URLs), followed by all internal rewrites, again in order from most- to least-specific.

I would suggest trying the following in example.com/.htaccess :

Options +FollowSymLinks -Indexes -MultiViews
RewriteEngine on
RewriteBase /
#
RewriteRule ^sub/workflow$ sub/index.php?option=com_user&view=login&return=aHR0cDovL3d [L]

Also, be sure to delete your browser cache before testing any changes to this code. Otherwise you will likely see stale pages and server responses cached by your browser, confusing and invalidating your test results.

Jim

g1smd

5:30 pm on Apr 18, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



... and once this rule is working, be aware that it is the browser that resolves the location of images, CSS and JS files mentioned on the page.

If those elements appear to be missing from your pages, you will need to alter your internal linking to look in the correct place for each of those things.

dcdeveloper

11:46 pm on Apr 18, 2010 (gmt 0)

10+ Year Member



First of all, Thank you for your prompt reply Jim (gdmorgan) and I did everything according to what you suggested, but unfortunately it is still not working.

I changed the RewriteBase to / instead of /sub and in regards to this RewriteBase, I was indeed intending to redirect all requests to the /sub server alias. this /sub directory acts like a subdomain in my case. However, just for the sake of making it works, I did just exactly like what you suggested.

Secondly, I added [L] by the end of my RewriteRule in which the RewriteRule now becomes like the following: RewriteRule ^sub/workflow$ sub/index.php?option=com_user&view=login&return=aHR0cDovL3d [L]

Last but not least, I had first cleaned up my browser cache and everything (saved data, session, cookies, etc) and got it run, alas it didn't work. the result turned up to be 404 page not found error :(

Did I miss something here in my .htaccess code?
my new .htaccess code is like the following now:

Options +FollowSymlinks -Indexes -MultiViews
RewriteEngine On
RewriteBase /
RewriteRule ^sub/workflow$ sub/index.php?option=option=com_user&view=login&return=aHR0cDovL3d [L]

jdMorgan

12:12 am on Apr 19, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



No, the code looks fine, as long as:

1) You are requesting example.com/sub/workflow with your browser
2) The code is located in example.com/.htaccess
3) The DocumentRoot for example.com is the same as the .htaccess file's directory
4) The file /sub/index.php exists

Lots of details, and all important... Since the code looks OK, I'd suspect one of the location-related requirements isn't being met. In that case, either the location or the code will need to change.

You'll need to flush your browser cache again every time you make a change to the .htaccess and upload it. Or just disable it completely -- as long as you're sure you won't forget to re-enable it after testing!

Jim

dcdeveloper

1:10 am on Apr 19, 2010 (gmt 0)

10+ Year Member



I have now changed my RewriteRule in .htaccess code into something like this:

RewriteRule ^workflow$ index.php?option=com_user&view=login&return=aHR0cDovL3d

and it works, since sub subfolder here acts as a subdomain, therefore I place the .htaccess in this folder which differs with that in the parent folder (i.e. www.example.com's .htaccess); However, another problem now occurs, that is, the page is missing its title. previously (before using a URL Rewriting), the title goes for something like "workflow" and now it just turn out to be like "welcome page" (default title of index.php).

To avoid confusion, let me describe briefly about how the title suppose to work. when only index.php is specified the title should go for the default one which is "welcome page" as soon as a querystring is appended on the url, the page will render differently according to the "option" parameter's value. In my case here, the option value is "com_user" therefore it should render the com_user component's layout which the title is meant to be "workflow".

Does the Rewriting process actually ignore the querystring of the rewritten filepath? because as you can see in my rewritten filepath, it has the required querystring parameters to cause the page to render the correct layout and I wonder why does not /sub/workflow which will be rewritten into
sub/index.php?option=com_user&view=login&return=aHR0cDovL3d render the layout similar to that of the unclean URL one, which is the index.php?option=com_user&view=login&return=aHR0cDovL3d (having correct layout and html page title)?

jdMorgan

1:36 pm on Apr 19, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Check (debug) the script itself, and look at two things:

1) How, specifically, does the script "GET" the query string? If it is taken from a variable related to the query string, then it will 'see' your rewritten query string. If it is taken from the originally-requested URI, then the rewrite will 'work,' but the script will be looking at the originally-requested path, whhich has no query string.

2) Look at how the script generates links for css and other objects included in the HTML (client-side URL-based includes, not server-side file includes). As g1smd pointed out above, the links for these client-side includes must be generated using either server-relative URL-paths (e.g. <img src="/images/logo.gif">), or full canonical URLs (e.g. <img src="http://example.com/images/logo.gif">). Page-relative links like "<img src=="images/logo.gif"> will not be correctly resolved by clients, because they will be using the "clean" URL as a base to resolve the relative links to URLs.

Jim

dcdeveloper

6:21 am on Apr 20, 2010 (gmt 0)

10+ Year Member



I have tested in my code now to retrieve all parameters of the querystring, which in this case is ?option=com_user&view=login&return=aHR0cDovL3d. now in my index.php?option=com_user&view=login&return=aHR0cDovL3d code, I commented out everything and I placed this piece of code at the very top:

(PHP Syntax)
<?php
if(isset($_GET['option']))
var_dump($_GET);
?>

After running that code once again by using the clean URL (i.e. /sub/workflow), interestingly the querystring value that is displayed is only "com_virtuemart" while the rest are gone. So, the value of parameter "view" and "return" are not displayed on the screen which means the rest of the querystring after the first one, were all being ignored by the RewriteRule function.

Any idea why this happen and how to get around this issue?

jdMorgan

1:20 pm on Apr 20, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



There's no 'magic' in mod_rewrite. If you put all the other name/value pairs in your substitution path, then they *were* there, and something else removed them.

Perhaps another rule was executed subsequent to this rule -- Note that you failed to include an [L] flag on this rule. Also, be aware that mod_rewrite processing is recursive; If any rule is invoked, then mod_rewrite will be restarted from the top. This will continue until a pass is made through all rules in the file and none are invoked. Therefore, mod_rewrite rules in .htaccess need to have mutually-exclusive patterns, or must have RewriteConds which prevent unwanted recursion.

Parts of query strings don't just disappear, but they can be over-written or removed by other rules.

Jim

dcdeveloper

5:42 am on Apr 21, 2010 (gmt 0)

10+ Year Member



Thanks A lot for your help, Jim! your solution is indeed wonderful :)
Everything is indeed according to what you have said. There is nothing wrong with the RewriteRule function. It seems like there is something wrong with the code where it attempts to get the querystring straight away using regex matching of the URL instead of using $_GET which of course the querystring is not there at the first place for the clean URL one.