Проблема mod_rewrite с относительным путем css / js - PullRequest
6 голосов
/ 29 апреля 2011

Привет, у меня проблема. Я хочу получить все запросы на перенаправление в индексный файл в главном каталоге, и я достиг этого, но есть проблемы с относительными путями.
Когда я ставлю адрес как: mydomain.com/something, он работает нормально, так как пути указаны относительно основного каталога.
Проблема в том, что я поставил что-то вроде: mydomain.com/something/somethingelse.

.htaccess файл:


Options FollowSymLinks
RewriteEngine On
# ignore anything that's an actual file
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
# redirect all other traffic to the index page
RewriteRule . index.php [L]

Есть идеи, как заставить работать css / js?


Edit:

Проблема в том, что файлы css / js не загружаются, когда введенный путь имеет несколько слешей
, например: mydomain.com/something/somethingelse

Ответы [ 4 ]

11 голосов
/ 29 апреля 2011

Без сомнения, лучше использовать абсолютный путь для статических файлов (css, js, images и т. Д.). Но если таких экземпляров много на нескольких страницах, попробуйте использовать базовый тег HTML , чтобы указать URL-адрес по умолчанию для относительных путей. например:

<base href="http://www.example.com/static/" />
3 голосов
/ 28 ноября 2015

Использование тега <base> является хорошим решением, и большинство браузеров, кажется, справляются с этим хорошо. За исключением некоторых проблем с IE, как и следовало ожидать ... Очевидно, вы также можете столкнуться с некоторыми другими забавными проблемами, см. Обсуждение здесь .

Так что для людей, где это не вариант, я посмотрел на альтернативу («трудный путь»).

Обычно вы храните CSS / JS / статические изображения / другие вещи, как это:

index.php
js/
css/
imgs/

и вы хотите, чтобы были доступны JavaScript, таблицы стилей и т. Д., Независимо от количества косых черт в URL. Если ваш URL-адрес /site/action/user/new, ваш браузер запросит

/site/action/user/css/style.css
/site/action/user/css/framework/fonts/icons.ttf
/site/action/user/js/page.js
/site/action/user/js/jquery/jquery.min.js
/site/action/user/js/some/library/with/deep/dir/structure/file.map

Итак, вот некоторые правила перезаписи для apache, чтобы решить это ... Во-первых, если цель действительно существует на диске, не переписывайте:

RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [L,QSA]

Другими словами, если имя файла запроса IF - это каталог, ИЛИ, если имя файла запроса IF - это файл, то не следует переписывать (-), последнее правило (L) и передавать любые параметры GET (QSA, добавление строки запроса). Вы также можете использовать

RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^.*$ - [L,QSA]

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

RewriteRule ^.*/js/(.*)$ js/$1 [L]      
RewriteRule ^.*/css/(.*)$ css/$1 [L]

Шаблон довольно очевиден, просто замените 'css' на имя каталога. С этим все еще остается проблема, особенно для больших веб-сайтов с большим количеством javascript и таблиц стилей, библиотек и т. Д. - регулярное выражение является жадным. Например, если у вас есть такой каталог javascript:

js/some/library/js/script.js

и ваш запрос переходит на /site/action/user/new, браузер запрашивает /site/action/user/new/js/some/library/js/script.js, который механизм перезаписи затем переписывает на

js/script.js

потому что первый .* является жадным и соответствует /site/action/user/new/js/some/library. Переключение на не жадное регулярное выражение на самом деле не имеет смысла, поскольку «механизм перезаписи повторяет все правила до тех пор, пока URI не будет одинаковым до и после итерации по правилам.»

Существует еще одна проблема, заключающаяся в том, что для каждого каталога, который необходимо освободить от перезаписи, требуется относительно «дорогое» регулярное выражение. Обе проблемы можно исправить, просто поместив каждый статический компонент в подкаталог с «необычным» именем (на самом деле это лучшее решение imo - любой, у кого есть идея, опубликуйте его).

Структура каталога будет выглядеть следующим образом:

index.php
mystrangedir/js/
mystrangedir/css/
mystrangedir/imgs/

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

RewriteRule ^.*/mystrangedir/(.*)$ mystrangedir/$1 [L]

Автоматизированные системы сборки (например, gulp, grunt ....) можно использовать для проверки, не существует ли mystrangedir в качестве каталога где-либо ниже его самого (что снова приведет к отключению механизма перезаписи).

Не стесняйтесь переименовывать mystrangedir во что-то более разумное, например static_content, но чем более разумным оно становится, тем более вероятно, что имя каталога уже используется в некоторой библиотеке. Если вы хотите абсолютно безопасное имя каталога, которое наверняка никогда не использовалось ранее, используйте криптографический хеш, например, 010f8cea4cd34f820a9a01cb3446cb93637a54d840a4f3c106d1d41b030c7bcb. Это довольно долго, чтобы соответствовать; Вы можете найти компромисс между уникальностью и производительностью регулярных выражений, если его сократить.

1 голос
/ 29 апреля 2011

Это проблема разрешения пути: при использовании относительного пути ./css на базовом пути /something он разрешается до /css, а при /something/somethingelse он разрешается до /something/css.

* 1007.* Это не может (или, скорее, не должно) быть исправлено с помощью mod_rewrite.Используйте абсолютные пути вместо относительных, поэтому /css вместо ./css.
1 голос
/ 29 апреля 2011
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

Должно работать, несмотря на комментарии.

Попробуйте добавить директивы RewriteLog и RewriteLogLevel, чтобы получить более подробные сведения.

...