Mod rewrite condition for subdomain with pass through - apache

I wanted to run this by you because I'm attempting to perfect an Apache mod rewrite rule, which works, but I'm going insane because my file paths are breaking.
Basically, I've set up a mod rewrite rule to redirect a subdomain, to a subdirectory in my docroot which contains a static index.html file. Existing rules are listed as follows:
RewriteCond %{HTTP_HOST} ^subdomain\.mydomain\.com$
RewriteCond %{REQUEST_URI} !^/subdirectory/
RewriteRule ^(.*)$ /subdirectory/$1 [PT]
The redirect works fine. What happens though, is my images are breaking. For example, '/subdirectory/img', with the following img tag, doesn't work for me:
<img src="img/some-image.png" />
Same thing happens when I move the image to root, and attempt to call the image directly minus the 'img/' path.
Does my redirect have anything to do with this? Or am I missing something? I was under the impression that using the Pass Through [PT] flag would mean that asset linking would work.
Any advice is greatly appreciated. Thanks for your help!
Mark.

This is because you are using a relative url path for your images. Either use an absolute path starting with a / or add the following base tag in head section of your webpage :
<base href="/">
Related :
Seo Friendly Url css img js not working

Issue resolved. The rule works perfectly, it was just the positioning in the .htaccess file. I moved it directly underneath the following:
RewriteEngine On
Images and JS assets are now loading fine. I also added a missing 'L' flag.
Final working code:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^subdomain\.mydomain\.com$
RewriteCond %{REQUEST_URI} !^/subdirectory/
RewriteRule ^(.*)$ /subdirectory/$1 [PT, L]

Related

Mod rewrite redirect every subdirectory to the same file

I have a website with a products.html file. Now, inside this file, I will have some Javascript code that checks the url to show the correct products/categories. This are some examples of the urls:
example.com/products
example.com/products/
example.com/products/shoes
example.com/products/shoes/
example.com/products/shoes/adidas
example.com/products/shoes/adidas/
example.com/products/shoes/adidas/adidas-predator-20.3
example.com/products/shoes/adidas/adidas-predator-20.3/
So basically, I want that everytime someone goes to the any of the above urls, I want to get the file products.html, I'll manage the rest with JS.
Also I want to be able to test this on my local machine. In this case, my URLs will be:
localhost/websites/myWebsite/products
localhost/websites/myWebsite/products/
localhost/websites/myWebsite/products/shoes
localhost/websites/myWebsite/products/shoes/
localhost/websites/myWebsite/products/shoes/adidas
localhost/websites/myWebsite/products/shoes/adidas/
localhost/websites/myWebsite/products/shoes/adidas/adidas-predator-20.3
localhost/websites/myWebsite/products/shoes/adidas/adidas-predator-20.3/
So I think we would need two htaccess files right?
You may use this single rule that will work on localhost and on production host as well:
RewriteEngine On
RewriteRule (?:^|/)products(?:/|$) products.html [L,NC]
With your shown samples could you please try following, you should place .htaccess file on same level where folder products is present. Also place the products.html in same level too.
RewriteEngine ON
RewriteCond %{REQUEST_URI} ^/(?:products)/?((?:shoes)/?((?:adidas)/?((?:adidas-predator-20\.3)/?)?)?)?$ [NC]
RewriteRule ^(.*)$ products.html [L]
If these are the only rules you will have then change L to END as an additional note here.

htaccess on Localhost refers to root, not folder

I am working on a website to make the URL's more SEO friendly with the htaccess, however, i bump into a problem when I set up the htaccess file. If I use the URLs I prefer to setup, i get refered back to the localhost and not towards the development map I am working in, so in this case, i get refered back to localhost/blog for example instead of localhost/jellyfish_rework/blog, so I end up with a view from my localhostor simply an error in the page.
The original link was http://localhost/jellyfish_rework/index.php?p=blog
Options +FollowSymLinks
RewriteEngine On
RewriteBase /jellyfish_rework/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)$ /?p=$1 [L]]
Does this have to do with the fact my anchors refer to <a href"/blog"></a>? Cause in the other anchor tags that I still refer to in the old way, I dont get the responds back I want (so the link stays http://localhost/jellyfish_rework/index.php?p=blog)
edit
the htaccess file is located in the localhost/jellyfish_rework/ as that is where the index file is.
Your last line (RewriteRule) should look like this
RewriteRule ^([^/]*)$ index.php?p=$1 [L]
Don't add a leading slash before.
Otherwise it will be like an absolute path (/index.php from root).
With the rule above and your RewriteBase, this rule will act this way:
If not existing file/folder then rewrite it to /jellyfish_rework/index.php?p=URI
Your old rule (with leading slash) was about:
If not existing file/folder then rewrite it to /index.php?p=URI
Note: since you're using relative paths, you must also change all your html links (css, javascript, images, links) with a leading /jellyfish_rework/ or use the base tag
<base href="/jellyfish_rework/">

Clean URL not working properly

Hey I'm struggling with this all day long and I'm new to clean URLs.
My Domain which i want to change:
http://www.domain.tld/ausflug.php?lang=de
to:
http://www.domain.tld/ausflug/lang/de/
via .htaccess. This is my code:
Options +FollowSymLinks
RewriteEngine on
RewriteRule ausflug/lang/(.*)/ ausflug.php?lang=$1
My Problems are:
If I navigate through my page, the url still is the ugly one.
And if I want to reach the page with the clean url, it won't display all the
css and js stuff.
Thanks for help!
First of all, replace your current code by this one (your htaccess should be in root folder)
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{THE_REQUEST} \s/ausflug\.php\?lang=([a-z]{2}) [NC]
RewriteRule . /ausflug/lang/%1/? [R=301,L]
RewriteRule ^ausflug/lang/([a-z]{2})/$ /ausflug.php?lang=$1 [L]
This will redirect domain.tld/ausflug.php?lang=de to domain.tld/ausflug/lang/de/ and will internally rewrite it (without any redirection loop error) to domain.tld/ausflug.php?lang=de.
For your second problem:
if I want to reach the page with the clean url, it won't display all
the css and js stuff
Simply use absolute paths for your links (with a leading slash).
Example: /css/file.css instead of css/file.css (otherwise it will look in wrong directory, since your rule is generating some virtual directories)
Or you can add this html tag <base href="/"> right after <head> in all pages (instead of replacing each links)

Ignore Rewrite Rule for images folder

I have a .htaccess file on a website I'm working on which rewrites urls from mydomain.com/sub/folder/ to mydomain.com?index.php?controller=sub&view=folder
Unfortunately the way I've written it means I can't access images, stylesheets and other linked files anymore. Could anyone tell me how best to exclude specific directories / URL requests from the rewrite rule?
Apologies if this is a bit of a newbie question, I'm still wrapping my head around this mod rewrite stuff!
The .htaccess file looks like this:
RewriteEngine on
RewriteRule ^([a-zA-Z0-9-]+)/?$ index.php?Controller=$1
RewriteRule ^([a-zA-Z0-9-]+)/([a-zA-Z0-9-_]+)/? index.php?Controller=$1&View=$2
If your images are in mydomain.com/images and you are linking to them using relative links on the page mydomain.com/sub/folder/ the browser is going to try to attempt to access the image via mydomain.com/sub/folder/images/i.gif. But if you change your links to absolute links, the browser will correctly attempt to load mydomain.com/images/i.gif. However, the RewriteRule will change it to: mydomain.com/index/php?Controller=images&View=i.gif. To avoid this you need to add a few RewriteConds:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9-_]+)\/?$ index.php?Controller=$1
RewriteRule ^([a-zA-Z0-9-_]+)/([a-zA-Z0-9-_]+)\/? index.php?Controller=$1&View=$2
So that when attempting at access an existing file/directory, don't rewrite to index.php.

How to do a mod_rewrite redirection to relative URL

I am trying to achieve a basic URL redirection for pretty-URLs, and due to images, CSS etc. also residing in the same path I need to make sure that if the URL is accessed without a trailing slash, it is added automatically.
This works fine if I put the absolute URL like this:
RewriteRule ^myParentDir/([A-Z0-9_-]+)$ http://www.mydomain.com/myParentDir/$1/ [R,nc,L]
But if I change this to a relative URL, so that I don't have to change it each time I move things in folders, this simply doesn't work.
These are what I tried and all do not work, or redirect me to the actual internal directory path of the server like /public_html/... :
RewriteRule ^myParentDir/([A-Z0-9_-]+)$ ./myParentDir/$1/ [R,nc,L]
RewriteRule ^myParentDir/([A-Z0-9_-]+)$ myParentDir/$1/ [R,nc,L]
What is the right way to do a URL redirection so that if the user enters something like:
http://www.mydomain.com/somedir/myVirtualParentDir/myVirtualSubdir
he gets redirected to (via HTTP 301 or 302):
http://www.mydomain.com/somedir/myVirtualParentDir/myVirtualSubdir/
Thanks.
EDIT: Adding some more details because it does not seem to be clear.
Lets say I am implementing a gallery, and I want to have pretty URLs using mod_rewrite.
So, I would like to have URLs as follows:
http://www.mydomain.com/somedir/galleries/cats
which shows thumbnails of cats, while:
http://www.mydomain.com/somedir/galleries/cats/persian
which shows one image from the thumbnails of all cats, named persian.
So in actual fact the physical directory structure and rewriting would be as follows:
http://www.domain.com/somedir/gallery.php?category=cats&image=persian
So what I want to do is put a .htaccess file in /somedir which catches all requests made to /galleries and depending on the virtual subdirectories following it, use them as placeholders in the rewriting, with 2 rewrite rules:
RewriteRule ^galleries/(A-Z0-9_-]+)/$ ./gallery.php?category=$1 [nc]
RewriteRule ^galleries/(A-Z0-9_-]+)/+([A-Z0-9_-]+)$ ./gallery.php?category=$1&image=$2 [nc]
Now the problem is that the gallery script in fact needs some CSS, Javascript and Images, located at http://www.domain.com/somedir/css, http://www.domain.com/somedir/js, and http://www.domain.com/somedir/images respectively.
I don't want to hardcode any absolute URLs, so the CSS, JS and Images will be referred to using relative URLs, (./css, ./js, ./images etc.). So I can do rewriting URLs as follows:
RewriteRule ^galleries/[A-Z0-9_-]+/css/(.*)$ ./css/$1 [nc]
The problem is that since http://www.domain.com/somedir/galleries/cats is a virtual directory, the above only works if the user types:
http://www.domain.com/somedir/gallaries/cats/
If the user omits the trailing slash mod_dir will not add it because in actual fact this directory does not actually exist.
If I put a redirect rewrite with the absolute URL it works:
RewriteRule ^galleries/([A-Z0-9_-]+)$ http://www.mydomain.com/subdir/galleries/$1/ [R,nc,L]
But I don't want to have the URL prefix hardcoded because I want to be able to put this on whatever domain I want in whatever subdir I want, so I tried this:
RewriteRule ^galleries/([A-Z0-9_-]+)$ galleries/$1/ [R,nc,L]
But instead it redirects to:
http://www.mydomain.com/home/myaccount/public_html/subdir/galleries/theRest
which obviously is not what I want.
EDIT: Further clarifications
The solution I am looking for is to avoid hardcoding the domain name or folder paths in .htaccess. I am looking for a solution where if I package the .htaccess with the rest of the scripts and resources, wherever the user unzips it on his web server it works out of the box. All works like that apart from this trailing slash issue.
So any solution which involves hardcoding the parent directory or the webserver's path in .htaccess in any way is not what I am looking for.
Here's a solution straight from the Apache Documentation (under "Trailing Slash Problem"):
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+[^/])$ $1/ [R]
Here's a solution that tests the REQUEST_URI for a trailing slash, then adds it:
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.+) http://www.example.com/$1/ [R=301,L]
Here's another solution that allows you to exempt certain REQUEST_URI patterns:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !example.php
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ http://domain.com/$1/ [L,R=301]
Hope these help. :)
This rule should add a trailing slash to any URL which is not a real file/directory (which is, I believe, what you need since Apache usually does the redirect automatically for existing directories).
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+[^/])$ $1/ [L,R=301]
Edit:
In order to prevent Apache from appending the path relative to the document root, you have to use RewriteBase. So, for instance, in the folder meant to be your application's root, you add the following, which overrides the physical path:
RewriteBase /
This might work:
RewriteRule ^myParentDir/[A-Z0-9_-]+$ %{REQUEST_URI}/ [NS,L,R=301]
However, I'm not sure why you think you need this at all. Just make your CSS / JS / image file rewrite rule look something like this:
RewriteRule ^galleries/([A-Za-z0-9_-]+/)*(css|js|images)/(.*)$ ./$2/$3
and everything should work just fine regardless of whether the browser requests /somedir/galleries/css/whatever.css or /somedir/galleries/cats/css/whatever.css or even /somedir/galleries/cats/persian/calico/css/whatever.css.
Ps. One problem with this rule is that it prevents you from having any galleries names "css", "js" or "images". You might want to fix that by naming those virtual directories something like ".css", ".js" and ".images", or using some other naming scheme that doesn't conflict with valid gallery names.
I'm not sure I complelty understand your problem.
The trailing slash redirection is done automatically on most Apache installation because of mod_dir module (99% of chance you'have the mod_dir module).
You may need to add:
DirectorySlash On
But it's the default value.
So. If you access foo/bar and bar is not a file in foo directory but a subdirectory then mod_dir performs the redirection to foo/bar/.
The only thing I known that could break this is the Option Multiviews which is maybe trying to fin a bar.php, bar.php, bar.a-mime-extension-knwon-by-apache in the directory. So you could try to add:
Option -Multiviews
And remove all rewriteRules. If you do not get this default Apache behavior you'll maybe have to look at mod-rewrite, but it's like using a nuclear bomb to kill a spider. Nuclear bombs may get quite touchy to use well.
EDIT:
For the trailing slash problem with mod-rewrite you can check this documentation howto, stating this should work:
RewriteEngine on
RewriteBase /myParentDir/
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+[^/])$ $1/ [R]