Вход на сайт
Задачка
11.08.10 20:19
Последний раз изменено 11.08.10 20:20 (voxel3d)
Торможу, никак сообразить не могу, можно ли одним mod_rewrite без поддержки серверных скриптов разрулить многоязыковую поддержку сайту, чтобы в адресной строке урлы были без параметров типа http://site/index.xhtml?lang=en, чтобы в урлах не было http://site/en/index.xhtml ?
Dropbox - средство синхронизации и бэкапа файлов.
NEW 11.08.10 22:20
в ответ voxel3d 11.08.10 20:19
самый простой вариант
.htaccess
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . ./controller.php
controller.php
<?php
$url = $_SERVER['REDIRECT_URL'];
[обработка $url]
?>
куда положишь controller.php - это уже твое личное дело, только путь нарисуй к нему
А в адресной строке можешь что угодно писать...
http://site/en/index.xhtml
http://site/lang/en/param1/x/param2/y/
и тп
NEW 11.08.10 22:53
в ответ GANDJUBAS 11.08.10 22:41
Ну, я думал в сторону подмены урла содержащего язык на урл без языка, но дальше мысль остановилась. 
Короче, это был бред.
У тебя, кстати, наверно, лучше REQUEST_URI использовать, оно не зависит от конфигурации сервера.

Короче, это был бред.
У тебя, кстати, наверно, лучше REQUEST_URI использовать, оно не зависит от конфигурации сервера.
Dropbox - средство синхронизации и бэкапа файлов.
NEW 12.08.10 16:06
Если мы имеем структуру директорий вроде следующей:
/
.htaccess
/de
.htaccess
index.html
/en
.htaccess
index.html
/de/index.html (/en/index.html аналогично):
<!doctype html>
<html lang='de'>
<head>
<meta http-equiv='content-type' content='text/html; charset=utf-8' />
<title>Willkommen</title>
</head>
<body>
<div style='text-align:right;border-bottom:1px solid grey;'>
< !-- Кнопки переключения локали -- >
<a href='?lang=de'>Deutsch</a> | <a href='?lang=en'>English</a>
</div>
<h1>Willkommen</h1>
</body>
</html>
/.htaccess
RewriteEngine On
RewriteBase /
# это переключатель локали. устанавливаем куки, обнуляем lang параметр во избежание зацикливания
RewriteCond %{QUERY_STRING} lang=(de|es|fr|it|ja|ru|en)
RewriteRule .* $0? [co=lang:%1:%{HTTP_HOST},R,L]
# если куки установлен идём в локальную субдиректорию
RewriteCond %{HTTP_COOKIE} lang=(de|es|fr|it|ja|ru|en)
RewriteRule .* %1/$0 [L]
# если нет - смотрим язык пользователя
RewriteCond %{HTTP:Accept-Language} ^(de|es|fr|it|ja|ru|en).*$
RewriteRule .* %1/$0 [L]
# наконец если ничего не сработало - устанавливаем дефолтную локаль
RewriteRule .* de/$0 [L]
# иначе при редиректе новая локаль сразу не видна
<ifmodule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 0 seconds"
</ifmodule>
/(de|en)/.htaccess
# вся эта шарманка нужна только на топовом уровне
RewriteEngine Off
Вот и все собственно. Если мы работаем с PHP, то тогда множественные директории отпадают, как отпадают и RewriteRule кроме первого. Далее просто транслируем мессиджи (например как здесь) устанавливая локаль из куки.
NEW 12.08.10 20:19
1. Учимся читать: можно ли одним mod_rewrite без поддержки серверных скриптов разрулить многоязыковую поддержку сайту - 11/8/10 20:19 (
voxel3d)
2. Пользователь может захотеть локаль отличную от языка браузера.
3. Выбранную локаль не мешало бы и запомнить. В том числе и для незарегистрированных/незалогинившихся пользователей.
4. Учим великий и могучий русский язык. Читая Ваше сообщение глаза можно сломать.

2. Пользователь может захотеть локаль отличную от языка браузера.
3. Выбранную локаль не мешало бы и запомнить. В том числе и для незарегистрированных/незалогинившихся пользователей.
4. Учим великий и могучий русский язык. Читая Ваше сообщение глаза можно сломать.
NEW 12.08.10 20:51
в ответ voxel3d 12.08.10 20:35
Так, как записано в моём ответе - да, всегда. А у тебя модуль вообще включен?
Я тут сравнил с редиректом, как его Jetty делает, есть несколько отличий, в том числе в длине контента:
Я тут сравнил с редиректом, как его Jetty делает, есть несколько отличий, в том числе в длине контента:
Apache:
HTTP/1.1 302 Found
Date: Thu, 12 Aug 2010 18:34:19 GMT
Server: Apache/2.2.11 (Win32) PHP/5.2.9-2
Set-Cookie: lang=de; path=/; domain=test.de
Location: http://test.de/
Content-Length: 199
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
====================================
Jetty:
-----------------------------
HTTP/1.1 302 Found
Content-Language: de
Location: http://localhost:8080/person/23
Content-Length: 0
Server: Jetty(8.0.0.M1)
NEW 12.08.10 20:55
Предыдущий пост - с выключенным expires. А если поставить его на нуль, то получается следующее, и браузер сразу делает перезапрос:
HTTP/1.1 302 Found
Date: Thu, 12 Aug 2010 18:52:48 GMT
Server: Apache/2.2.11 (Win32) PHP/5.2.9-2
Set-Cookie: lang=en; path=/; domain=test.de
Location: http://test.de/
Cache-Control: max-age=0
Expires: Thu, 12 Aug 2010 18:52:48 GMT
Content-Length: 199
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
NEW 12.08.10 20:58
в ответ femidav 12.08.10 20:51
Да, модуль включён. Без него заметна необходимость обновления странички после смены локали.
Тестирую с включённым tamper data в лисе. Хожу по своему сайту, везде 304:
Status=Not Modified - 304
Date=Thu, 12 Aug 2010 18:55:53 GMT
Server=Apache/2.2.14 (Ubuntu)
Connection=Keep-Alive
Keep-Alive=timeout=15, max=100
Etag="a036b-28a2-48da471dc1031;48da4e387004b"
Expires=Thu, 12 Aug 2010 18:55:53 GMT
Cache-Control=max-age=0
Тестирую с включённым tamper data в лисе. Хожу по своему сайту, везде 304:
Status=Not Modified - 304
Date=Thu, 12 Aug 2010 18:55:53 GMT
Server=Apache/2.2.14 (Ubuntu)
Connection=Keep-Alive
Keep-Alive=timeout=15, max=100
Etag="a036b-28a2-48da471dc1031;48da4e387004b"
Expires=Thu, 12 Aug 2010 18:55:53 GMT
Cache-Control=max-age=0
Dropbox - средство синхронизации и бэкапа файлов.
NEW 12.08.10 21:20
в ответ femidav 12.08.10 21:10
По идее все равно лучше задать разным типам файлов разные сроки жизни. Я все статичные ресурсы (css, js, img) организую в одной субдиректории и там задаю ExpiresDefault "access plus 1 year" (это максимум). А если что поменяется, так на это есть URL fingerprinting. Но это все, если треффик надо оптимизировать.
NEW 12.08.10 21:24
в ответ femidav 12.08.10 21:20
Как задать для определённого типа данных expires?
RewriteCond %{QUERY_STRING} lang=(en|fr|de)
RewriteRule .* $0? [CO=lang:%1:%{HTTP_HOST},R,L]
$0? во что раскрывается? В (допустим, выбрано de) "de?" ?
RewriteCond %{QUERY_STRING} lang=(en|fr|de)
RewriteRule .* $0? [CO=lang:%1:%{HTTP_HOST},R,L]
$0? во что раскрывается? В (допустим, выбрано de) "de?" ?
Dropbox - средство синхронизации и бэкапа файлов.
NEW 12.08.10 21:42
в ответ voxel3d 12.08.10 21:24
C долларом это выражения найденные в RewriteRule, с процентами - в условии. $0 - это полностью весь match в rule, %1 - первое в условии, то бишь 'de'.
Вот мой .htaccess из папки с ресурсами:
Вот мой .htaccess из папки с ресурсами:
RewriteEngine on
RewriteCond %{REQUEST_URI} .*?\.r[0-9]+\.(css|js)$
RewriteRule (.*?)\.r[0-9]+\.(css|js)$ $1\.$2
<ifmodule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 year"
</ifmodule>
<ifmodule mod_deflate.c>
<FilesMatch "\.(css|js)$">
SetOutputFilter DEFLATE
</FilesMatch>
</ifmodule>
<ifmodule mod_headers.c>
<FilesMatch "\.(jpg|jpeg|png|gif)$">
Header set Cache-Control "public"
</FilesMatch>
</ifmodule>
http://www.askapache.com/htaccess/using-filesmatch-and-files-in-htaccess.html
NEW 12.08.10 21:52
в ответ femidav 12.08.10 21:42
RewriteRule .* $0? [CO=lang:%1:%{HTTP_HOST},R,L]
Я не понимаю тогда. Url запроса "127.0.0.1/index.xhtml?lang=de" преобразуется к "127.0.0.1/index.xhtml?lang=de?" ? Или оно до параметра только берётся?
Я не понимаю тогда. Url запроса "127.0.0.1/index.xhtml?lang=de" преобразуется к "127.0.0.1/index.xhtml?lang=de?" ? Или оно до параметра только берётся?
Dropbox - средство синхронизации и бэкапа файлов.
NEW 12.08.10 22:02
Вопросительный знак поставлен чтобы отсечь параметры. Установить куки, отсечь параметры для красоты, и перенаправить на тот же адрес, чтобы там уже второе правило перенаправило запрос в нужную подпапку. Можно и без этого, но тогда локаль в адресе будет болтаться. То бишь имеем:
127.0.0.1/index.xhtml?lang=de -> 127.0.0.1/index.xhtml? code 302, -> перезапрос 127.0.0.1/index.xhtml -> 127.0.0.1/de/index.xhtml
Пропиши следующее в httpd.conf, виднее будет:
<IfModule rewrite_module>
RewriteLog /path/to/logs/rewrite.log
RewriteLogLevel 2
</IfModule>
в ответ voxel3d 12.08.10 21:52
В ответ на:
RewriteRule .* $0? [CO=lang:%1:%{HTTP_HOST},R,L]
Я не понимаю тогда. Url запроса "127.0.0.1/index.xhtml?lang=de" преобразуется к "127.0.0.1/index.xhtml?lang=de?" ?
RewriteRule .* $0? [CO=lang:%1:%{HTTP_HOST},R,L]
Я не понимаю тогда. Url запроса "127.0.0.1/index.xhtml?lang=de" преобразуется к "127.0.0.1/index.xhtml?lang=de?" ?
Вопросительный знак поставлен чтобы отсечь параметры. Установить куки, отсечь параметры для красоты, и перенаправить на тот же адрес, чтобы там уже второе правило перенаправило запрос в нужную подпапку. Можно и без этого, но тогда локаль в адресе будет болтаться. То бишь имеем:
127.0.0.1/index.xhtml?lang=de -> 127.0.0.1/index.xhtml? code 302, -> перезапрос 127.0.0.1/index.xhtml -> 127.0.0.1/de/index.xhtml
Пропиши следующее в httpd.conf, виднее будет:
<IfModule rewrite_module>
RewriteLog /path/to/logs/rewrite.log
RewriteLogLevel 2
</IfModule>
NEW 13.08.10 12:53
Нашёл косяк, только не понимаю, чей. Хромиуму при первом заходе, если нет установленной куки, сервер выдёт 500, превышена глубина рекурсии. Оно рекурсивно пытается редиректить начиная с / -> /en/ -> /en/en/ -> ... Возникает только в хроимуме 5.0.375.99 (51029) Ubuntu 10.04. Хром в виндовсе нормально отрабатывает.
Dropbox - средство синхронизации и бэкапа файлов.
NEW 13.08.10 14:22
1. Да.
2. Блин, чудеса. Перестало циклиться. Кэш, куки и т.д., ессно, чистил и тогда и сейчас. Сервер рестартил и тогда и щас.
Вот кусок лога:
Хедер уже показать не могу.
2. Блин, чудеса. Перестало циклиться. Кэш, куки и т.д., ессно, чистил и тогда и сейчас. Сервер рестартил и тогда и щас.

В ответ на:
[Fri Aug 13 12:54:44 2010] [error] [client 192.168.0.11] Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalR
ecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
[Fri Aug 13 12:54:44 2010] [debug] core.c(3063): [client 192.168.0.11] r->uri = /en/en/en/en/en/en/en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/en/en/en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/en/en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /index.xhtml
[Fri Aug 13 12:54:44 2010] [error] [client 192.168.0.11] Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalR
ecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
[Fri Aug 13 12:54:44 2010] [debug] core.c(3063): [client 192.168.0.11] r->uri = /en/en/en/en/en/en/en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/en/en/en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/en/en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /en/index.xhtml
[Fri Aug 13 12:54:44 2010] [debug] core.c(3069): [client 192.168.0.11] redirected from r->uri = /index.xhtml
Хедер уже показать не могу.
Dropbox - средство синхронизации и бэкапа файлов.
NEW 24.08.10 01:56
в ответ femidav 13.08.10 18:39
Подскажи, как мне заставить работать четыре строки идущие после RewriteBase?
Они меняют mime-тип для ИЕ, чтобы он мог открыть .xhtml файлы. Без каталогов, когда всё в корне лежало, оно работало, сейчас - нет.
Они меняют mime-тип для ИЕ, чтобы он мог открыть .xhtml файлы. Без каталогов, когда всё в корне лежало, оно работало, сейчас - нет.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} \.xhtml$
RewriteCond %{HTTP_USER_AGENT} MSIE [OR]
RewriteCond %{HTTP_ACCEPT} application/xhtml\+xml\s*;\s*q=0\.?0*(\s|,|$)
RewriteRule .* - [T=text/html]
RewriteCond %{QUERY_STRING} lang=(en|fr|de)
RewriteRule .* $0? [CO=lang:%1:%{HTTP_HOST},R,L]
RewriteCond %{HTTP_COOKIE} lang=(de|fr|en)
RewriteRule .* %1/$0 [L]
RewriteCond %{HTTP:Accept-Language} ^(en|fr|de).*$
RewriteRule .* %1/$0 [L]
RewriteRule .* fr/$0 [L]
ExpiresActive On
ExpiresDefault "access plus 0 seconds"
Dropbox - средство синхронизации и бэкапа файлов.
NEW 24.08.10 11:09
в ответ femidav 24.08.10 02:07
Ты имеешь в виду выставить принудительно для .xhtml глобально mime-тип text/html или использовать мой xhtml код внутри .html файлов?
Я х.з. - я так и не нашёл нигде информации, в какой режим браузеры заходят в подобных случаях, то ли в нормальном остаются, то ли в режим совместимости.
Я х.з. - я так и не нашёл нигде информации, в какой режим браузеры заходят в подобных случаях, то ли в нормальном остаются, то ли в режим совместимости.
Dropbox - средство синхронизации и бэкапа файлов.