I have an index.php, profile.php files in localhost/project
I've written following code in my .htaccess file to have localhost/project/profile.php?u=sam by visiting localhost/project/sam
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^([a-zA-Z0-9_-]+)$ profile.php?u=$1
RewriteRule ^([a-zA-Z0-9_-]+)/$ profile.php?u=$1
When I visit http://localhost/project/sam it diplays what I want without errors. But when I visit http://localhost/project/sam/ (with trailing / ) it displays the page with plain text, that means the css file is not attached.
Anyone know the reason for this? And help me to solve this?
You are probably using relative URI paths to reference those external resources. And relative URIs are resolved on a base URI that is the URI of the current document if not specified otherwise.
So when using a relative URI path like css/style.css on /project/sam it is resolved to /project/css/style.css; but when used on /project/sam/ it is resolved to /project/sam/css/style.css.
You could fix this by either using the absolute URI path /project/css/style.css or by changing the base URI with the BASE element. But note that the latter will affect all relative URIs and not just relative URI paths.
You're using a relative link to your css.
How do you include that css file? If you generate the path from PHP, it might contain a double '/' if your request contains a trailing '/'. Please check your HTML output and moidify the path of the CSS.
Either require the slash, or forbid it, or you'll never know whether relative links need to go uplevel or not. For example to forbid the slash:
RewriteRule ^(.*)/$ $1 [R]
which will redirect the client to the same page without the slash included. It's best to have a single canonical URI for an object anyway.
Related
I am using WAMP Server on my PC as a local host. I want to re-write my URL without PHP extension and remove query string(but readable) as from http://myproject/post.php?page=page_slug to http://myproject/post/page_slug and I should be able to read "page_slug" via echo $_GET['page']; on "post.php" page. FOr this purpose, I have a project with a simple hierarchy is shared below.
Project_Folder:
->css/style.css
->image/logo.jpg
->js/script.js
->.htaccess
->index.php
->about.php
->contact.php
->blog.php
->post.php
->page.php
Now I want to remove all .PHP extensions from my URL so I used the below .htaccess code and it is working fine.
# Options is required by Many Hosting
Options +MultiViews
#Remove .PHP Extension And Force Redirect To Without .PHP File Name In URL
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [NC,L]
#RewriteCond %{THE_REQUEST} \s([^?]*)\?p=(\S+)\s [NC]
#RewriteRule ^ %1/%2? [R=301,L]
After the above code, I am able to re-write my URLs from http://myproject/post.php?page=page_slug to http://myproject/post?page=page_slug means .PHP extension is now removed successfully.
Now to make my URL free from query string pattern, I used the below code after the above code in my .htaccess file.
RewriteCond %{THE_REQUEST} \s([^?]*)\?p=(\S+)\s [NC]
RewriteRule ^ %1/%2? [R=301,L]
After the above code, I am able to re-write my URLs from http://myproject/post?page=page_slug to http://myproject/post/page_slug means query string is now removed successfully but my JS and CSS are broken now as shown below.
But my every file is perfect as when I remove the upper second code set then it is working properly. Also, they are loading fine as shown below.
I noticed one thing that my CSS and JS files data is now changed with my PHP file data as shown below. Why this is happening...???
So what is the fix for this...??? Also, remember that I need to read QUERY STRING parameters also in my file.
The "problem" is that you appear to be using relative URL-paths to your static resources (CSS, JS and images). So this is a client-side URL resolution issue. You should be using root-relative (starting with a slash) or absolute (with scheme + hostname) URLs to your assets so they can be located regardless of URL-path depth. (Note that any requests that your JS makes, eg. AJAX, should also be root-relative or absolute.)
The problem is not so much with .htaccess, but when you change the URL from /post.php?page=page_slug to /post/page_slug then any client-side relative URLs are going to resolve relative to /post/, not / (the document root) as before.
The request for the JS (and CSS) files result in a 404, so the 404 HTML error document is most probably being parsed as JS and failing (ie. "Uncaught SyntaxError: Unexpected token: '<'" - due to a <!DOCTYPE html> or opening <html> tag).
A possible workaround (to avoid changing your URLs) is to use a base HTML element in the head section to indicate what any relative URLs should be resolved relative to, overriding the URL of the current document. However, this has some additional caveats if you are using in-page anchors of the form href="#element" - since they will now be resolved relative to the document stated in the base element and not the current document.
See also my answer to the following question on the Webmasters stack that goes into more detail on this:
https://webmasters.stackexchange.com/questions/86450/htaccess-rewrite-url-leads-to-missing-css
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(.*)\.(css|js|htc|pdf|jpg|jpeg|gif|png|ico)$ [NC]
RewriteRule ^(.*)$ index.php?path=$1 [QSA,L]
This .htaccess redirects everything to index.php?path=SOMETHING where I can pick it up (SOMETHING path) and show appropriate content (views).
The problem is with including .css/.js files.
If I use www.website.com/something everything works (css path is like /css/style.css and it's searching in the www.website.com/css/style.css). But if I use www.website.com/something/2 everything crashes because it's searching in www.website.com/something/css/style.css folder.
How to set root (?) everytime to www.website.com (whatever path is)? So I should still have acccess to my 'path' variable but everything should point to the website root and not /some/... path when including my files.
The problem is in the way how you write links to css/js/image files.
Instead of including css/js/images using relative URLs to the current page:
href="css/style.css"
you should use URLs relative to the root (notice the leading slash):
href="/css/style.css"
or use absolute URLs (that will include domain name -- much less preferred approach).
This is a typical mistake when designing website (html part) when site uses Nice URLs/URL Rewritting. This is -- it's now that rewrite engine breaks URLs -- it's browser that sends them like that (/something/css/style.css) in first place.
The idea is to redirect http://thesite.com/fr/page1.htm to http://thesize/page1.htm?lang=fr
I could find around how to set .htaccess and redirection is working with this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^fr/([^/]+)$ /$1?lang=fr [L,QSA]
But the problem I can not find a solution is from the redirected page itself. The paths to folders seem to be relative to the subdirectory /fr as to html it looks like it is in the subdirectory fr. What would be a clean solution for this? a in the on each page?
Thanks!
I'd say using an absolute path is the way to go in this case.
Adding <base> leads to other problems, because it changes the relative root for the whole page
Using relative paths is too tiresome if you have multiple possible levels of sub-directories.
I am in a new project and I'm designing the URL structure,
the thing is I want URLs look like this:
/category-23/keyword/5/
Where the normal page is:
/search.php?q=keyword&cat=23&page=5
So my question is, cat and page fields, must be optional, I mean if I go to /keyword it should be
/search.php?q=keyword (page 1)
and if I go to
/category/keyword should be:
/search.php?q=keyword&cat=category&p=1
and also if I go to
/keyword/5/ it must be: /search.php?q=keyword&p=5
Now I have my .htaccess like this:
RewriteEngine On
RewriteBase /
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)/(.*)/(.*)$ search.php?q=$2&cat=$1&page=$3 [L]
I cannot make it working and the CSS / image files don't load.
I'd thank a lot who could give me a solution.
You can do this with four rules, one for each case:
RewriteRule ^([^/]+)$ search.php?q=$1
RewriteRule ^([^/]+)/([0-9]+)$ search.php?q=$2&p=$1
RewriteRule ^([^/]+)/([^/]+)$ search.php?q=$2&cat=$1&p=1
RewriteRule ^([^/]+)/([^/]+)/([0-9]+)$ search.php?q=$2&cat=$1&p=$3
And with this rule in front of the other rules, any request that can be mapped onto existing files will be passed through:
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^ - [L]
Now your last issue, that externally linked resources cannot be found, is due to that you’re probably using relative URL paths like css/style.css or ./css/style.css. These relative references are resolved from the base URL path that is the URL path of the URL of the document the references are used in. So in case /category/keyword is requested, a relative reference like css/style.css is resolved to /category/keyword/css/style.css and not /css/style.css. Using the absolute URL path /css/style.css makes it independent from the actual base URL path
While i know this was answered succinctly by #Gumbo a few months back, I ran into a similar issue recently... and didn't want to include full/absolute paths in my app, to keep it dynamic and not having a bunch APP_PATH (php) vars all over the place... so I just added a base[href] html tag with the
like so...
<base href="http://<?php echo $_SERVER[HTTP_HOST];?><?php echo APP_PATH;?>"/>
Hoping that helps others... and this is not trying to discount #Gumbo's reply in the least... they're right-e-o on :).
Shouldn't it be
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule ^ - [L]
in #Gumbo's answer above? Works with me like that. If it is a file (like CSS), let it pass through.
So I rewrote my paths to something like: URL/really/nice/paths/ using mod_rewrite rules like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [PT,L]
</IfModule>
The question is how could I rewrite the paths for js/css/image files too, so when they are requested with a relative path from URL/really/nice/path/ to be served from URL/scripts/, URL/styles/ and URL/images/ folders instead? Can this be done without using RewriteBase?
When URLs are rewritten, the client doesn't know it. So when a client looks at a page at the URL "example.com/some/url/" and the page references an image in "images/image.jpg", the client looks for the image in "example.com/some/url/images/image.jpg" even though the page actually resides in "example.com/some/other/url/". That's the problem you're facing, right?
There are three main solutions to this problem:
Use absolute paths to resources instead of relative ones.
Use the <base> tag to ensure that the client knows the root upon which to build its relative URLs is different from the page's apparent URL.
Add a new rule for "some/url/images/" in your rewrite rules.
Option 1 is probably the best idea, and you'll find that most sites that use URL rewriting use it, including Stack Overflow itself. Option 2 is frowned upon, but works and is relatively easy. Option 3 is the most difficult to maintain, as URL rewriting exceptions and special cases can appear as you're defining new rules.
The most maintainable solution is to use absolute URLs.