проблема с utf-8 символами и apache2 переписывает правила

Я вижу, что сообщение проверить utf-8 в htaccess переписывает правило, и я думаю, что это является большим, но более фундаментальная проблема я имею сначала:

Я должен был расшириться для обработки utf-8 символов для параметров строки запроса, названий каталогов, файлов, и привыкший в дисплеях к пользователям и т.д.

Я настроил свой Apache с DefaultCharset utf-8 и также свой php, если это имеет значение. Мой оригинал переписывает правило, фильтрованное все кроме регулярного A-Za-z и подчеркивания и дефиса. и это работало. Что-либо еще дало бы Вам 404 (который является тем, что я хочу!) Теперь, однако кажется, что все соответствует, включая материал, который я не хочу, однако, хотя это, кажется, соответствует ему, не входит в строку запроса, если это не регулярная A-Za-z_-символьная строка.

Я нахожу это сбивающим с толку, потому что, как в правиле говорится, помещает то, чему Вы соответствовали в строку запроса:

Вот исходное правило:

RewriteRule ^/puzzle/([A-Za-z_-]+)$ /puzzle.php?g=$1 [NC]

и вот пересмотренное правило:

RewriteRule ^/puzzle/(\w+)$ /puzzle.php?g=$1 [NC]

Я внес изменение, потому что где-нибудь я считал, что \w соответствует ВСЕМ альфа-символам, где, поскольку A-Zetc. только соответствует тем без диакритических знаков и материала.

Это, кажется, не имеет значения, какое из тех правил я использую: Вот то, что происходит:

В приложении у меня есть это:

echo $_GET['g'];

Если я подаю его URL как http://mydomain.com/puzzle/USA, это повторяет "США" и хорошо работает.
Если я подаю его URL как http://mydomain.com/puzzle/México, это ничего не повторяет для этого и предупреждает меня, что индекс g не определяется и конечно не получает ресурсы для Мексики.
если я подаю его URL как http://mydomain.com/puzzle/fuzzle/buzzle/j.qle, это делает то же самое.
Этот последний случай должен быть 404!

И это делает это, неважно, которое из вышеупомянутых правил я использую. Я настроил переписать журнал

   RewriteLogLevel 5
   RewriteLog /opt/local/apache2/logs/puzzles.httpd.rewrite

но это пусто.

Вот от регулярного журнала доступа (он дает состояние 200),

[26/May/2010:11:21:42 -0700] "GET /puzzle/M%C3%A9xico HTTP/1.1" 200 342
[26/May/2010:11:21:54 -0700] "GET /puzzle/M/l.foo HTTP/1.1" 200 342

Что может я делать для получения этих $ % # $ (*#!!! символы, но не наклонная черта, точка или другая неальфа в мою программу, и однажды там, это будет декодировать их правильно??? Действительно ли posix обуглил бы работу классов немного лучше? Есть ли что-либо еще, что я должен настроить?

11
задан Community 23 May 2017 в 12:00
поделиться

4 ответа

Это ответ на ответ эсминца, но он стал слишком длинным.

Я отказался от кодирования URL в Unicode, потому что его достаточно легко декодировать для отображения. Так что, может быть, это основная проблема. В конце концов, я просто буду использовать url_encode в php для этого, но я подумал, что попробую онлайн, просто для проверки: я пошел на http://www.opinionatedgeek.com/dotnet/tools/urlencode/Encode .aspx и попытался закодировать Мексику, и получилось M% c3% a9xico. Я зашел на указанный вами сайт и попробовал, и вышло M% E9xico другое !! Что он??? Думаю, мне придется принять все, что мне действительно даст функция php. Но у обоих есть 9, что означает, что я должен принимать цифры, а также%. Это ВСЕ, что мне нужно было включить?

Я надеюсь, что запросы, запрашивающие подлинные подкаталоги, будут НЕ соответствовать этому правилу, если это то, что вы имеете в виду, обходя его, я бы предпочел, чтобы они фактически отображали статические страницы в подкаталогах. Вот почему я действительно хочу исключить / что, как я думал, сделал. Но, похоже, соответствует чему-либо после / включая вложенные подкаталоги и идет к файлу puzzle.php.

Вот что я пробовал, но без радости: я использовал это правило: RewriteRule ^ / puzzle / ([A-Za-z0-9 _% -] +) $ /puzzle.php?g=$1 [NC] как видите, я добавил в группу% и 0-9. Мне нужно избегать% или что-то в этом роде? Я читал, что только \ нужно экранировать в квадратных скобках. Надеюсь, ты это имеешь в виду. Будет ли это единственным дополнительным символом, который вы получите, закодировав любую возможную строку Unicode? затем я передал 2 разные версии Мексики с кодировкой URL.Для M% E9xico я теперь получаю 404 и это сообщение: Запрошенный URL / головоломка / México не найден на этом сервере. Для M% c3% a9xico я теперь получаю это сообщение на 404: Запрошенный URL / головоломка / MÃ © xico не найден на этом сервере. А для несуществующих подкаталогов теперь выдается 404, как и должно. Так что теперь просто не работает правило перезаписи. Это прогресс. Также в журнале перезаписи стали появляться записи: Вот некоторые. Я найду в Google, как читать эти журналы:

kidd108d-mac3:logs tpdick$ cat puzzles.httpd.rewrite 
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (2) init rewrite engine with requested uri /puzzle/M?xico
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) applying pattern '^/puzzle/([A-Za-z0-9_%-]+)$' to uri '/puzzle/M?xico'
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (1) pass through /puzzle/M?xico
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] add path info postfix: /Users/tpdick/Sites/puzzles/puzzle.php -> /Users/tpdick/Sites/puzzles/puzzle.php/M?xico
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] strip per-dir prefix: /Users/tpdick/Sites/puzzles/puzzle.php/M?xico -> puzzle.php/M?xico
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] applying pattern '^(.*)/GeoP-Test/puzzle/(.*)$' to uri 'puzzle.php/M?xico'
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (1) [perdir /Users/tpdick/Sites/puzzles/] pass through /Users/tpdick/Sites/puzzles/puzzle.php
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) [perdir /Users/tpdick/Sites/puzzles/] add path info postfix: /Users/tpdick/Sites/puzzles/puzzle.php -> /Users/tpdick/Sites/puzzles/puzzle.php/M?xico
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) [perdir /Users/tpdick/Sites/puzzles/] strip per-dir prefix: /Users/tpdick::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (2) init rewrite engine with requested uri /puzzle/México
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) applying pattern '^/puzzle/([A-Za-z0-9_%-]+)$' to uri '/puzzle/México'
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (1) pass through /puzzle/México
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] add path info postfix: /Users/tpdick/Sites/puzzles/puzzle.php -> /Users/tpdick/Sites/puzzles/puzzle.php/México
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] strip per-dir prefix: /Users/tpdick/Sites/puzzles/puzzle.php/México -> puzzle.php/México
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] applying pattern '^(.*)/GeoP-Test/puzzle/(.*)$' to uri 'puzzle.php/México'
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (1) [perdir /Users/tpdick/Sites/puzzles/] pass through /Users/tpdick/Sites/puzzles/puzzle.php
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) [perdir /Users/tpdick/Sites/puzzles/] add path info postfix: /Users/tpdick/Sites/puzzles/puzzle.php -> /Users/tpdick/Sites/puzzles/puzzle.php/México

Что теперь ??

1
ответ дан 3 December 2019 в 11:51
поделиться

On ...

RewriteRule ^/puzzle/(\w+)$ /puzzle.php?g=$1 [NC]

Кто-нибудь поправит меня, если я ошибаюсь, но разве это не означает, что запросы на подкаталоги просто обходят это правило?

Кроме того, ленивый способ решить эту проблему - также сгруппировать в символе "%". Насколько я знаю, все, с чем вам разрешено работать, - это кодировка URL-адреса с любым URL-адресом. На самом деле, см .: http://www.blooberry.com/indexdot/html/topics/urlencoding.htm

Я уверен, что есть более продвинутые и лучшие способы сделать это, но это должно решить вашу немедленную проблема.

1
ответ дан 3 December 2019 в 11:51
поделиться

Я бы предложил вам активировать MultiViews и забыть о mod_rewrite. Добавьте в конфигурацию apache в соответствующем разделе Directory/VirtualHost:

Options +MultiViews
#should already be set to this, but it doesn't hurt:
AcceptPathInfo Default

Нет, вы всегда можете опустить расширения, пока клиент включает соответствующий тип mime в свой заголовок Accept.

Теперь запрос /puzzle/whatever будет отображаться на /puzzle.php, а $_SERVER['PATH_INFO'] будет заполнен /whatever.


Если вы хотите сделать это с помощью mod_rewrite, это также возможно. Тестовая строка для RewriteRule неэкранирована (части %xx преобразуются в байты, которые они представляют). Вы можете получить оригинальную приведенную строку, используя %{REQUEST_URI} или %{THE_REQUEST} (последний также содержит метод HTTP и версию).

По традиции веб-браузеры используют кодировку UTF-8 в URL-адресах. Это означает, что "México" будет закодирован в M%C2%82xico, а не в M%82xico, что было бы ожидаемо, если бы браузеры использовали ISO-8859-1. Также, [a-zA-Z] не будет соответствовать é. Однако это должно сработать:

RewriteCond %{REQUEST_URI} ^/puzzle/[^/]*$
RewriteRule ^/puzzle/(.*)$ /puzzle.php?q=$1 [B,L]

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

Вы должны знать, что RewriteRule не поддерживает юникод. Все, кроме .*, может дать (потенциально) неверные результаты. Даже [^/] может не сработать, поскольку / "символ" (читай: байт) может быть частью многобайтовой последовательности символов. Если бы RewriteRule знал юникод, ваше решение с \w должно работать.

Поскольку вы не хотите сопоставлять подкаталоги, а RewriteRule ^/puzzle/[^/]* не является опцией, эта проверка откладывается на RewriteCond, который использует (экранированный) %{REQUEST_URI}.

1
ответ дан 3 December 2019 в 11:51
поделиться

Это решение основано на: http://www.dracos.co.uk/code/apache-rewrite-problem/

Попробуйте следующие правила перезаписи:

AddDefaultCharset UTF-8
RewriteEngine On
RewriteCond %{THE_REQUEST} /puzzle/([^?\ /]+)
RewriteRule ^puzzle/(.*)$ puzzle.php/%1 [L]

Как получить параметр запроса:

<?php
// Get query param
$g = substr($_SERVER['PATH_INFO'], 1); 
echo "<p>g: $g</p>";

// Test if '/' is present in URL for 404's
$g2 = substr($_SERVER['REQUEST_URI'], 8); 
if (strpos($g2, '/') === false) {
    // do stuff
} else {
    // Send 404 header here
    echo "<p>404</p>";
}
?>

В этом решении вы должны отправить 404 с php.

1
ответ дан 3 December 2019 в 11:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: