开发者

Relative URLs with .htaccess

开发者 https://www.devze.com 2023-04-10 00:51 出处:网络
I have a custom PHP framework in which everything after the domain is sent to PHP as a $_GET variable, like so:

I have a custom PHP framework in which everything after the domain is sent to PHP as a $_GET variable, like so:

RewriteRule ^(.*)$ index.php?page_request=$1 [QSA,L]

All routing is done by a router file. For example, http://domain.tld/page gets sent to http://domain.tld?page_request=home.

However, if I have a directory-like structure (i.e. http://domain.tld/page/), the request is sent, but any relative URLs in the HTML are now relative to /page, even though we're still in the root level in the domain.

To clarify:

Going to http://domain.tld/page and requesting res/css/style.css in HTML returns a stylesheet.

Going to http://domain.tld/page/ and requesting res/css/style.css returns an 404 error, because the page/ directory doesn't actually exist.

What's the best way to work around this? This seems really simple, but I'm not quite good enough with .htaccess yet to do it off the top of my head. Thanks for any answers in advance.

Edit: Also, my .htaccess file contains:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

Edit #2: Yes, I know about using the leading /.

However, I can't do that with this particular website, because it's a subfolder on a server, so linking to / would go to the root of the server and not the site.

If I put /subfolder/css for every link on the site, that would not only get tedious, but also problematic were the subfolder to change. Is there a better way to work around开发者_StackOverflow社区 this?


The other answers that say you have to absolutize the paths are correct. If you are working in a subfolder, there are two things that you can/should do to help:

1) Use RewriteBase in your htaccess file

RewriteEngine on
RewriteBase /framework/

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)/?$    index.php?url=$1    [QSA,L]

2) Create a constant in your framework that has that same path

define('FULL_PATH', '/framework');

Then each time you create a URL in html, make sure you do something like

<a href="<?= FULL_PATH ?>/your/remaining/path">

It's a little bit of extra work to think about this each time you create a URL on the page, but it will serve you well in the long run.


Relative URLs are not affected by apache rewrite rules. They're up to the browser. If the browser sends a request for /some/random/path/, you can rewrite it all you want on the server end, but the browser will interpret all relative urls as being inside /some/random/path/

If you want to include res/css/style.css from the root, you should prefix it with a leading slash to make that clear: /res/css/style.css


If you are looking for a dynamic solution (in case you move the entire site to a subfolder or different domain), you can use PHP to get the absolute path of a file you are running (like your main php file) and then store that path in a constant or variable that you can use for all of your links.

if ( !isset($_SERVER['HTTPS']) ) { $domain = 'http://'.$_SERVER['HTTP_HOST']; }
else {  $domain = 'https://'.$_SERVER['HTTP_HOST']; };
$root = $domain.str_replace($_SERVER['DOCUMENT_ROOT'], '', dirname(__FILE__) );

The first two lines just setup how the path will start, whether it should be http or https. The third line gets the full server path to the file that this code is in, removes the unnecessary parts (user/public_html) and stores it in the variable $root.

You can then link your files this way:

<script src="<?php echo $root; ?>/jquery.js"></script>

With this method, the site can be moved to any domain or subfolder, and you don't have to worry about breaking links.

Edit: I just thought of an easier way to use this method. Rather than using absolute links, you could use your normal relative links along with this in the head of the document:

<base href="<?php echo $root; ?>/">

This rewrites the base path for your relative links to the correct directory. Then this will work:

<script src="jquery.js"></script>


You need to absolutize all the paths in your html code so you link to your CSS using absolute paths instead of relative.

If you are running into this problem, I suspect your CSS looks like this:

<link href="res/css/style.css" rel="stylesheet" type="text/css" media="screen" />

But it should look like:

<link href="/res/css/style.css" rel="stylesheet" type="text/css" media="screen" />

Do the same for javascript, css, image files and links and you should be fine with your rewrite rules.

0

精彩评论

暂无评论...
验证码 换一张
取 消