Относительные URL-адреса с .htaccess

#php #.htaccess

#php #.htaccess

Вопрос:

У меня есть пользовательский фреймворк PHP, в котором все после домена отправляется на PHP в виде переменной $ _GET, например:

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

Вся маршрутизация выполняется файлом маршрутизатора. Например, http://domain.tld/page отправляется на http://domain.tld?page_request=home .

Однако, если у меня есть структура, подобная каталогу (т. Е. http://domain.tld/page/ ), Запрос отправляется, но любые относительные URL-адреса в HTML теперь относятся к /page , даже если мы все еще находимся на корневом уровне в домене.

Чтобы уточнить:

Переход http://domain.tld/page и запрос res/css/style.css в HTML возвращает таблицу стилей.

Переход http://domain.tld/page/ и запрос res/css/style.css возвращает ошибку 404, поскольку page/ каталог фактически не существует.

Каков наилучший способ обойти это? Это кажется действительно простым, но я еще недостаточно хорошо разбираюсь в .htaccess, чтобы делать это с головы до ног. Заранее спасибо за любые ответы.

Редактировать: кроме того, мой файл .htaccess содержит:

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

Редактировать # 2: Да, я знаю об использовании ведущего / .

Однако я не могу сделать это с этим конкретным веб-сайтом, потому что это подпапка на сервере, поэтому ссылка на / будет идти в корень сервера, а не на сайт.

Если бы я помещал /subfolder/css для каждой ссылки на сайте, это было бы не только утомительно, но и проблематично, если бы нужно было изменить вложенную папку. Есть ли лучший способ обойти это?

Ответ №1:

Другие ответы, в которых говорится, что вам нужно абсолютизировать пути, верны. Если вы работаете во вложенной папке, есть две вещи, которые вы можете / должны сделать, чтобы помочь:

1) Используйте RewriteBase в вашем файле htaccess

 RewriteEngine on
RewriteBase /framework/

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

2) Создайте константу в своей среде, которая имеет тот же путь

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

Затем каждый раз, когда вы создаете URL-адрес в html, убедитесь, что вы делаете что-то вроде

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

Думать об этом каждый раз, когда вы создаете URL-адрес на странице, требует немного дополнительной работы, но в долгосрочной перспективе это сослужит вам хорошую службу.

Ответ №2:

Правила перезаписи apache не влияют на относительные URL-адреса. Они зависят от браузера. Если браузер отправляет запрос на /some/random/path/ , вы можете переписать его сколько угодно на стороне сервера, но браузер будет интерпретировать все относительные URL-адреса как находящиеся внутри /some/random/path/

Если вы хотите включить res/css/style.css из корня, вы должны добавить к нему косую черту, чтобы это было ясно: /res/css/style.css

Комментарии:

1. Я знаю, что Apache не влияет на относительные URL-адреса, но я включил .htaccess, потому что именно это вызывает проблему. Я не могу использовать начальную косую черту, потому что сайт находится во вложенной папке.

2. Вы должны по этой причине, вы можете предшествовать ссылкам с помощью /subfolder/ … в противном случае это единственный способ, которым браузеры найдут правильное содержимое, когда ваши правила перезаписи выглядят как URL-адреса каталогов / файлов.

3. Есть ли какой-нибудь способ обойти это? Кажется повторяющимся / не СУХИМ делать это для каждого URL-адреса на сайте.

4. Я не вижу другого пути. Если вы выводите свой html с помощью шаблонов или с помощью PHP, вы можете установить глобальную переменную like define('BASE_URL', 'http://yoursite.com/subfolder'); , а затем вернуть какую-либо функцию, подобную get_url('css/main/style.css'); той, которая будет возвращать http://yoursite.com/subfolder/css/main/style.css , чтобы вы могли использовать эту функцию везде.

Ответ №3:

Если вы ищете динамическое решение (в случае, если вы перемещаете весь сайт во вложенную папку или другой домен), вы можете использовать PHP, чтобы получить абсолютный путь к файлу, который вы запускаете (например, к вашему основному php-файлу), а затем сохранить этот путь в константе или переменной, которую вы можете использоватьдля всех ваших ссылок.

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

Первые две строки просто настраивают, как будет начинаться путь, должен ли он быть http или https.
Третья строка получает полный путь сервера к файлу, в котором находится этот код, удаляет ненужные части (user / public_html) и сохраняет его в переменной $root .

Затем вы можете связать свои файлы таким образом:

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

С помощью этого метода сайт можно переместить в любой домен или подпапку, и вам не нужно беспокоиться о разрыве ссылок.

Редактировать: я просто подумал о более простом способе использования этого метода. Вместо того, чтобы использовать абсолютные ссылки, вы можете использовать свои обычные относительные ссылки вместе с этим в заголовке документа:

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

Это переписывает базовый путь для ваших относительных ссылок в правильный каталог. Тогда это будет работать:

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

Ответ №4:

Вам нужно абсолютизировать все пути в вашем html-коде, чтобы вы ссылались на свой CSS, используя абсолютные пути вместо относительных.

Если вы столкнулись с этой проблемой, я подозреваю, что ваш CSS выглядит следующим образом:

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

Но это должно выглядеть так:

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

Сделайте то же самое для javascript, css, файлов изображений и ссылок, и вы должны быть в порядке с вашими правилами перезаписи.

Комментарии:

1. Спасибо, я знал о начале косой черты, но см. Мой Отредактированный вопрос выше.

2. Сделайте /subfolder/content/, и это сработает. Единственная «проблема» заключается в том, что если вы когда-нибудь переместите свой сайт, вам, возможно, придется отредактировать много путей, но вы можете использовать /subfolder/css вместо просто /css