mod_rewrite with Trailing Slash breaks CSS/IMG/SCRIPTS paths - php

I'm trying to make mod_rewrite the first sub-directory string from url in order to create similar functionality as 'jsfiddle.net saved url's within a class/db. The script works fine and does the rewrite.
e.g. of url
http://jsfiddle.net/RyEue/
This works fine (loads all css, scripts, etc.):
http://www.domain.com/787HHJ2
This is what I've used in the past which does the trick.
The problem Is when ending URL with last slash, script, css and others loose path.
http://www.domain.com/787HHJ2/
rewrite script:
DirectoryIndex index.php index.html
Options +FollowSymlinks
RewriteEngine On # Turn on the rewriting engine
#RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{QUERY_STRING} !.
RewriteRule ^.+/?$ index.php [QSA,L]
Unsure if this has to do with Rewritebase, I've tried multiple ways.
PS. I've tried setting paths to absolute (e.g. src="/img/theimage.jpg") without luck.

1. Make sure you have css/images/js etc linked relative to root folder (with leading slash): /styles/main.css
2. Add one of these ruls before current one:
# do not touch files with .css/.js/.jpg etc extensions
RewriteRule \.(css|js|jpg|png|gif)$ - [L]
or
# do not touch any resources in images/css/js folders
RewriteRule ^(images|css|js)/ - [L]
3. Clear browser caches and restart (sometimes browser may display cached page/resource when rewrite rule was fixed which brings a lot of confusion).

Try escaping
RewriteRule ^.+\/?$ index.php [QSA,L]

Related

htaccess: relative paths not working properly

First, what I am trying to achieve:
I am testing under the base http://example.com/subdir and this is where all subfolders , index.php and .htaccess are.
I have 3 groups of rules as shown in the .htaccess (extra rules removed):
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine on
# Convert item/edit/xx -> index.php?p=edit&id=xx
# Convert item/remove/xx -> index.php?p=remove&id=xx
#RewriteCond %{REQUEST_URI} ^/item [NC]
#RewriteCond %{QUERY_STRING} ^id=([0-9]+)$ [NC]
RewriteRule ^item/([a-z]+)/([0-9]+)$ index.php?p=$1&id=$2 [NC,L]
# Convert category/yyyy -> customer/pagination.php?category=yyyy
#RewriteCond %{QUERY_STRING} category=([a-zA-Z\s]+)$
RewriteRule ^customer/category/([a-zA-Z\s]+)$ customer/pagination.php?category=$1 [NC,L]
# Convert action/about -> index.php?p=about
# Convert action/terms -> index.php?p=terms
#RewriteCond %{QUERY_STRING} p=([a-z]+)$
RewriteRule ^action/([a-z]+)$ index.php?p=$1 [NC,L]
</IfModule>
The first problem I faced was the RewriteCond not working (giving Path not found), so it is commented out for the moment.
RewriteRule works fine with absolute path (e.g. RewriteRule ^action/([a-z]+)$ http://example.com/subdir/index.php?p=$1 [NC,L]), however this causes the browser to display the real URL therefore I'm trying to make it work with relative paths.
My issue is that after a first redirect the first part of the link on the left is added to the path, i.e. http://example.com/subdir becomes http://example.com/subdir/action after clicking action/about link.
Defining RewriteBase or prepending slashes to the URLs only makes things worse.
I will be grateful to an eagle-eyed expert who can spot the root cause of my problem.
The first problem is that %{REQUEST_URI} always includes the full path. So, your condition could be changed to:
RewriteCond %{REQUEST_URI} ^/subdir/item [NC]
The second problem would actually not be solved using .htaccess. You just need to tell the browser what you want. So, you can use one of two methods.
Use the <base> element (which will apply to all relative URIs on the page):
<base href="/subdir" />
Use a relative path to the URL shown in the browser:
Click here
If you really wanted to solve the problem using .htaccess, the only real way to do so would be to remove the duplicated directory after it has been requested.

how to remove the .php extension from url, for a file named same like a folder

I used this code
## remove the php extention
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
This works for some files the e.g. example.com/contact, but doesn't work when I have a .php file that is also a directory. For example, in the root folder:
science.php
science - folder
The articles are in categories e.g. http://example.com/science/themost-blabla.php - this works, the .php extionsion doesn't appear in the URL.
So I want to know if is any possible to hide the .php extension to science.php because when I type example.com/science ... it redirects me to the content of the science folder....
Index of /science directory:
afla-care-a-fost-primul-meci-televizat-de-fotbal-din-lume-1937-arsenal.php
cazinoul-din-constanta.php cele-7-minuni-ale-lumii.php
descoperire-colosala-a-epavei-navei-spaniole-san-jose-ce-avea-la-bord-o-avere-impresionanta.php
imagini/ mitologia-greaca.php poenaru.php
top-10-cele-mai-importante-inventii-romanesti-din-istorie.php
top-5-enigme-ale-lumii.php turnul-eiffel.php
So, can I do something to hide the extension to this page? Or do I need to change the name of the file - to not be the some as the folder?
Try this
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
One of the "problems" is that mod_dir will try to "fix" the URL when accessing a directory by appending a slash to the end of the URL. However, this can be disabled.
# Prevent mod_dir from automatically appending slashes to directories
DirectorySlash Off
# Disable directory listings
# In cases where there is a directory with no similar .php file and no DirectoryIndex
Options -Indexes
# If a PHP file exists for the requested URL then rewrite to this
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*) $1.php [L]
If required, bare directories (or rather, the DirectoryIndex) can be accessed by explicitly appending a slash to the URL. eg. example.com/science/. However, this is presumably unnecessary (and probably best avoided to avoid user confusion) since I assume example.com/science (no trailing slash, ie. science.php) returns your "science" category content. Without a DirectoryIndex document, example.com/science/ will simply return a 403 Forbidden. Alternatively you could explicitly remove trailing slashes from such URLs with an external redirect.

.htaccess spits our full URL rewritten URL on folder name

I have the following .htaccess:
RewriteEngine On
RewriteBase /sandbox/
RewriteRule ^(assets)($|/) - [L]
RewriteRule ^(.*)$ lib/script/bootstrap.php?route=$1.php [NC,L,QSA]
What I am doing is redirecting all requests (except for my assets - img, css, js) to my bootstrap script, which will handle the request via the route parameter, which includes the URL request.
This works fine in most cases, except for when I have a call such as:
http://www.example.com/sandbox/admin, where admin is a folder that exists in my directory, amongst other folders. This folder contains various pages that are accessible, aswell as an index.php file that my bootstrap.php routing will redirect requests from the above URL to it, by default.
My problem is that when I attempt to hit the page: http://www.example.com/sandbox/admin, my htaccess (as far as I know) is rewriting the visible URL to http://www.example.com/sandbox/admin/?route=admin.php, which is not as pretty. I believe it's because there's some conflict going on with the fact that the above URL is a valid URL pointing to my /admin/ folder, but I would like my .htaccess to ignore this and send this aswell to my bootstrap.php (line 4 of my .htaccess). What am I doing wrong?
Here is the requests coming in my browser:
UPDATE:
Strangely, http://www.example.com/sandbox/admin/ works fine, but not http://www.example.com/sandbox/admin (notice the trailing slash).
If you have real folders you need to use a condition to ignore real files and folders. All other requests will get routed to your bootstrap file. (If I understand your issue correctly.)
RewriteEngine On
RewriteBase /sandbox/
RewriteRule ^(assets)($|/) - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/?$ lib/script/bootstrap.php?route=$1.php [NC,L,QSA]

unextected redirection un xampp for windows

i'm creating a website, before uploading the site to web hosting i'm using XAMPP on windows. i was trying to use Search Engine Friendly URLs, for example:
http://localhost/mysite/[something]
to
http://localhost/mysite/index.php?p=[something]
i tried this .htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([0-9A-Za-z]+) index.php?id=$1 [QSA,L] #and also tried http://localhost/mysite/index.php?p=$1
before this i tried more examples but they didn't work. The real problem is that for example if y type
localhost/mysite/some_page
i get an error (403), using the [R] flag i realized that redirection is: http://localhost/C:/XAMPP/htdocs/mysite/index.php?p=some_page
i removed htaccess file and restarted apache but problam persist with some urls
Perhaps I'm trying to solve a different problem, but if the [something] always leads to content served by your index.php, then just send all requests to index.php and let that page use the URL string to get the variable you need to serve the right content (ie the string after the /).
You may need to turn off MultiViews in your .htaccess using Options -MultiViews.
The following is what you need in your .htaccess
RewriteBase /
# Where "/" is the location of your index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [QSA, L]
Hope this helps.

htaccess rewrite ".../pages/about.php" to ".../about"

I've searched and found a lot of questions on this site and elsewhere that are very similar, but I've tried implementing and modifying all the suggestions I've found and none of it works. I realize this is a very basic question an I am extremely frustrated because nothing I'm trying is working.
With that having been said... I am trying to organize my content pages within kurtiskronk.com/pages/... (e.g. kurtiskronk.com/pages/about.php)
What I want to do is make it so that I can simply link to kurtiskronk.com/about ... So how do I go about stripping "pages/" and ".php"? I don't have a ton of content pages, so it's not a big deal if I have to specify for each page, though something dynamic would be handy.
NOTES: I am using Rackspace Cloud hosting, and WordPress is installed in /blog. My phpinfo() can be seen at http://kurtiskronk.com/pages/phpinfo.php
This is my existing .htaccess file (in the root)
php_value register_globals "on"
Options +FollowSymLinks
RewriteEngine On
#301 redirect to domain without 'www.'
RewriteCond %{HTTP_HOST} ^www\.kurtiskronk\.com$ [NC]
RewriteRule ^(.*)$ http://kurtiskronk.com/$1 [R=301,NC]
RewriteBase /
RewriteCond %{ENV:PHP_DOCUMENT_ROOT}/pages/$1 -f
RewriteRule ^(.*)$ pages/$1 [L]
RewriteCond %{ENV:PHP_DOCUMENT_ROOT}/pages/$1.php -f
RewriteRule ^(.*)$ pages/$1.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/ blog/index.php [L]
# PHP - MAIL
php_value mail.force_extra_parameters -kurtis#kurtiskronk.com
I tested and the rewrite works with the line below (/about as URL brings up file /pages/about.php), but then the homepage gives a 500 Internal Server Error:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /pages/$1.php [L]
So I'm still sort of in the same boat as before, and as a follow-up, possibly more difficult question, if you go to http://kurtiskronk.com/weddings I am using SlideShowPro (flash) w/ SSP Director (self-hosted) as the back-end for it. When it pulls up a new image, it adds the following after /weddings ... "#id=album-152&num=content-9698"
There are four sections of the portfolio
# Homepage (kurtiskronk.com) id=album-148 ($id is constant for this section)
# Weddings (/weddings) id=album-152 ($id is constant for this section)
# Portraits (/portraits) id=album-151 ($id is constant for this section)
# Commercial (/commercial) id=album-150 ($id is constant for this section)
Assuming we get kurtiskronk.com/weddings to rewrite successfully without breaking anything, how would we make the total URL something cleaner kurtiskronk.com/weddings/9698 since the $num is the only thing that will change within a given section?
Kurtis, thanks for the extra information. It's a lot easier to give a specific answer to this.
My first comment is that you need to separate out in your thinking URI space -- that is what URIs you want your users to type into their browser -- and filesystem space -- what physical files you want to map to. Some of your mappings are URI->URI and some are URI->FS
For example you want to issue a permanent redirect of www.kurtiskronk.com/* to kurtiskronk.com/*. Assuming that you only server the base and www subdomains from this tree, then this cond/rule pair should come first, so that you can assume that all other rules only refer to kurtiskronk.com.
Next, you need to review the RewiteBase documentation. .htaccess files are processed in what Apache calls a Per-Directory context and this directive tells the rewrite engine what to assume as the URI base which got to this directory and .htaccess file. From what I gather, your blog is installed in docroot/blog (in the filesystem, and that you want to get to directory by typing in http://kurtiskronk.com/blog/ but that this .htaccess file is for the root folder -- that is the base should be (this goes before the www mapping rule)
DirectorySlash On
DirectoryIndex index.php
RewriteBase /
#301 redirect to domain without 'www.'
RewriteCond %{HTTP_HOST} ^www\.kurtiskronk\.com$ [NC]
RewriteRule ^(.*)$ http://kurtiskronk.com/$1 [R=301,NC]
You can add some field dumps look for REDIRECT_* in the Server or Environment table in the phpinfo O/P to see if these are sensible. For example:
RewriteWrite ^(.*)$ - \
[E=TESTDR:%{DOCUMENT_ROOT}/pages/$1.php,E=TESTPDR:%{DOCUMENT_ROOT}/pages/$1.php]
Your next rule is that if the file exists in the subdirectory pages then use it:
RewriteCond %{DOCUMENT_ROOT}/pages/$1 -f
RewriteRule ^(.*)$ pages/$1 [NS,L]
[Note that some shared service sites don't set up DOCUMENT_ROOT properly for the rewrite engine so you may need to run a variableinfo script (<?php phpinfo(INFO_ENVIRONMENT | INFO_VARIABLES); to see if it sets up alternatives. On your site you have to use %{ENV:PHP_DOCUMENT_ROOT} instead.]
Your next rule is that if the file exists, but with the extension .php in the subdirectory pages then use it:
RewriteCond %{DOCUMENT_ROOT}/pages/$1.php -f
RewriteRule ^(.*)$ pages/$1.php [NS,L]
Now redirect any blog references to the blog subdirectory unless the URI maps to a real file (e.g. the blog stylesheets and your uploads.)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/ blog/index.php [L]
A complication here is that WP may be using a poorly documented Apache feature call Path Info that is a script can act as a pseudo directory so http://kurtiskronk.com/blog/tag/downtown/ is redirected to docroot/blog/index.php/tag/downtown/ which is then executed by `docroot/blog/index.php using /tag/downtown/ as the PATH_INFO. But this is one for Wordpress experts to comment on. If this last rule doesn't work then try:
RewriteRule ^blog/(.*) blog/index.php/$1 [L]
PS. I like your site. I wish I was that young again :(
Postscript
When you say "it doesn't work", what doesn't with this .htaccess?
http://kurtiskronk.com/phpinfo,
http://kurtiskronk.com/phpinfo.php,
http://kurtiskronk.comblog/tag/downtown/
It's just that these rules work for these tests (with domain swapped) on mine. (One way is to move or copy the above variableinfo.php to the various subdirectories. If necessary temporarily rename the index.php to index.php.keep, say, and copy the variableinfo.php to the index.php file. You can now enter the various URI test patterns and see what is happening. Look for the REDIRECT_* fields in the phpinfo output, and the SCRIPT_NAME will tell you which is being executed. You can add more {E=...] flags to examine the various pattern results. (Remember that these only get assigned if the rule is a match.
Lastly note the changes above especially the additional NS flags. For some reason mod_rewrite was going directly into a subquery which was resulting in redirect: being dumped into the file pattern. I've had a look at the Apache code and this is a internal botch to flag that further redirection needs to take place (which then replaces this or backs out). However this open bug indicates that this backout can be missed in sub-queries and maybe that's what is happening here. Certainly adding the NS flas cured the problem on my test environment.
PS. Note the added explicit DirectoryIndex directive and also that whilst http://kurtiskronk.com will run the root index.php, the explicit /index.php version will run the one in pages, because that's what your rules say.
Here is a simple solution. You can use it apache conf file(s) or in .htaccess (easier to set up when you're trying).
mod_rewrite has to be enabled.
For example, use .htaccess in your DocumentRoot with:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /pages/$1.php [L]
It will redirect /about to /pages/about.php, and any other page.
The "RewriteCond" part is to authorize access to an existing file (eg: if you had an "about" file at the root of your site, then it will be served, instead of redirecting to /pages/about.php).
Options +FollowSymLinks
RewriteEngine On
RewriteRule /([0-9]+)$ /pages/$1.php [L]
Put something like this in your .htaccess file. I guess that is what you want.
Juest a redirect from a simple url to a longer url.

Categories