Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RewriteRule causes page to reload twice

I shaped two different RewriteRules for my page:

# Enable URL Rewriting
RewriteEngine on

# exclude followed stuff
RewriteRule ^(js|img|css|favicon\.ico|image\.php|anprobe|content|libs|flash\.php|securimage)/ - [L,QSA,S=2]

# conditions (REQUEST dont point @ file|dir|link)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-F
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l

# rules
RewriteRule ^(?!index\.php)brillen/(.*(brillen)|360|neu)/(.*)([a-zA-Z0-9]{5}-[a-zA-Z0-9]{5}(?!\.))(.*)$     /index.php/brillen/$1?art_id=$4&$5&%{QUERY_STRING}      [NS,QSA,L]
RewriteRule ^(?!index\.php)(.*)$                                                            /index.php/$1                                   [NS,QSA,L]

... and I'm encountering a strange problem, which lies in every request causing the page internally to load twice, which leads to the problem that db actions and email dispatching are also executed twice.

Does anyone have an idea concerning that?

Thanks in advance!

Note 1: All requested resources are valid and available according to the browser's resource tracking.

Note 2: May the problem originate in retaining and post-processing the PATH_INFO? (/index.php/$1 => /index.php/foo/bar/...)

like image 790
proximus Avatar asked May 10 '11 09:05

proximus


1 Answers

The rewrite Engine cannot make a single HTTP request run twice. It routes the HTTP request for Apache to either a static file, a proxy function, or a module (like PHP) with alteration in the request. But it cannot clone the request and give it 2 times to apache.

When you have any "run twice" problem chances are that you are hit by the empty image url bug. In fact it's not really a bug it's a feature of HTML (at least before HTML5) and a feature of url-parsing.

If you get somewhere an empty GET url, HTML states that the browser should re-send the same query (the one that gave him the current page) with same parameters. This can make a POST request happen 2 times (if the requested 1st page were a POST). So where are these empty GET url? Most of the time you get either :

<IMG SRC="" ...> (in the HTML)

or:

url() (in the css)

or:

<script type="text/javascript" src=""></script>
<link rel="stylesheet" type="text/css" href=""> (in the HTML headers)

Read also @Jon answer about the favicon query. You should always test the result without browsers behaviours by using wget or telnet 80 queries.

Update: detailled explanations and followups available on this blog with HTML5 additions which should remove this behavior for modern browsers.

like image 151
regilero Avatar answered Sep 20 '22 12:09

regilero