The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex
Where to place mod_rewrite rules
ReplyDeletemod_rewrite rules may be placed within the httpd.conf file, or within the .htaccess file. if you have access to httpd.conf, placing rules here will offer a performance benefit (as the rules are processed once, as opposed to each time the .htaccess file is called).
Logging mod_rewrite requests
logging may be enabled from within the httpd.conf file (including <Virtual Host>):
# logs can't be enabled from .htaccess
# loglevel > 2 is really spammy!
RewriteLog /path/to/rewrite.log
RewriteLogLevel 2
Common use cases
to funnel all requests to a single point:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f # ignore existing files
RewriteCond %{REQUEST_FILENAME} !-d # ignore existing directories
RewriteRule ^(.*)$ index.php?query=$1 # map requests to index.php and append
# as a query string
handling 301/302 redirects:
RewriteEngine on
RewriteRule ^oldpage.html$ /newpage.html [R=302] # 302 Redirect
RewriteRule ^oldpage2.html$ /newpage.html [R=301] # 301 Redirect
note: external redirects are implicitly 302 redirects:
# this rule:
RewriteRule ^somepage.html$ http://google.com
# is equivalent to:
RewriteRule ^somepage.html$ http://google.com [R]
# and:
RewriteRule ^somepage.html$ http://google.com [R=302]
forcing SSL
RewriteEngine on
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://mysite.com/$1 [R,L]
common flag usage:
[R] force a redirect (default 302)
[R=301] force a 301 redirect
[L] stop rewriting process (see note below in common pitfalls)
[NC] case insensitive matches
you can mix and match flags:
RewriteRule ^olddir(.*)$ /newdir$1 [L,NC]
Common pitfalls
mixing mod_alias style redirects with mod_rewrite
# Bad
Redirect 302 /somepage.html http://mysite.com/otherpage.html
RewriteEngine on
RewriteRule ^(.*)$ index.php?query=$1
# Good (use mod_rewrite for both)
RewriteEngine on
RewriteRule ^somepage.html$ /otherpage.html [R=302,L] # 302 redirect, and stop processing
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?query=$1 # handle other redirects
note: you can mix mod_alias with mod_rewrite, but it involves more work than just handling basic redirects as above.
context affects syntax
within .htaccess files, a leading slash is not used in the pattern:
# given: GET /directory/file.html
# .htaccess
# result: /newdirectory/file.html
RewriteRule ^directory(.*)$ /newdirectory$1
# .htaccess
# result: no match!
RewriteRule ^/directory(.*)$ /newdirectory$1
# httpd.conf
# result: /newdirectory/file.html
RewriteRule ^/directory(.*)$ /newdirectory$1
# Works in both contexts:
RewriteRule ^/?directory(.*)$ /newdirectory$1
[L] is not last! (sometimes)
within the .htaccess context, [L] will not force mod_rewrite to stop. it will continue to trigger internal sub-requests:
RewriteRule ^dirA$ /dirB [L] # processing does not stop here
RewriteRule ^dirB$ /dirC # /dirC will be the final result
our rewrite log shows the details:
rewrite 'dirA' -> '/dirB'
internal redirect with /dirB [INTERNAL REDIRECT]
rewrite 'dirB' -> '/dirC'
The deal with RewriteBase:
ReplyDeleteYou almost always need to set RewriteBase. If you don't, apache guesses that your base is the physical disk path to your directory. So start with this:
RewriteBase /
if you need to 'block' internal redirects / rewrites from happening in the .htaccess, take a look at the
ReplyDeleteRewriteCond %{ENV:REDIRECT_STATUS} ^$
condition, as discussed here.
Equation can be done with following example:
ReplyDeleteRewriteCond %{REQUEST_URI} ^/(server0|server1).*$ [NC]
# %1 is the string that was found above
# %1<>%{HTTP_COOKIE} concatenates first macht with mod_rewrite variable -> "test0<>foo=bar;"
#RewriteCond search for a (.*) in the second part -> \1 is a reference to (.*)
# <> is used as an string separator/indicator, can be replaced by any other character
RewriteCond %1<>%{HTTP_COOKIE} !^(.*)<>.*stickysession=\1.*$ [NC]
RewriteRule ^(.*)$ https://notmatch.domain.com/ [R=301,L]
Dynamic Load Balancing:
If you use the mod_proxy to balance your system, it's possible to add a dynamic range of worker server.
RewriteCond %{HTTP_COOKIE} ^.*stickysession=route\.server([0-9]{1,2}).*$ [NC]
RewriteRule (.*) https://worker%1.internal.com/$1 [P,L]
Another great feature are rewrite-map-expansions. They're especially useful if you have a massive amout of hosts / rewrites to handle:
ReplyDeleteThey are like a key-value-replacement:
RewriteMap examplemap txt:/path/to/file/map.txt
Then you can use a mapping in your rules like:
RewriteRule ^/ex/(.*) ${examplemap:$1}
More information on this topic can be found here:
http://httpd.apache.org/docs/2.0/mod/mod%5Frewrite.html#mapfunc