Я пытаюсь создать спокойный API с помощью mod_rewrite.
У меня есть правило:
RewriteRule v2/(.*)$ v1/index.php?request=$1 [QSA,NC,L]
Однако путь может содержать строки в кодировке base64 (т.е. могут иметь + или /), и они декодируются до того, как попадут в PHP.
Например, если я перейду к
/v2/cards/9VwQLli%2Bf0ogFl19AVRFLuztbp8cP0rYCgXBu3H9%2BDc%3DBe
PHP получает $_REQUEST['request']
так как cards/9VwQLli f0ogFl19AVRFLuztbp8cP0rYCgXBu3H9 Dc=Be'
.
И что еще хуже, если я добавлю туда косую черту (например, 9VwQLli%2Bf0ogFl19AVRFLuztbp8c%2FP0rYCgXBu3H9%2BDc%3DBe
- в %2F
это косая черта) я получаю 404.
Как я могу предотвратить это?
Примечание: я пробовал B
и NE
флаги, но они не имели никакого эффекта. Я полагаю, что в качестве хака я мог бы просто преобразовать все +
персонажей _
и все /
к -
, или, возможно, даже двойной URL-адрес, кодирующий его, но мне было интересно, есть ли способ лучше.
Вы этого не сделаете. Веб-серверу разрешено декодировать символы с процентной кодировкой, которые не декодируются в специальные символы, до применения правил перезаписи, и разрешено декодировать оставшуюся часть символов с процентной кодировкой перед передачей данных в ваше веб-приложение. (См. RFC 3986.)
Что вам следует делать, так это применять шаблон фронтального контроллера в своем веб-приложении и самостоятельно обрабатывать весь процент декодирования (и маршрутизации запросов). В этом случае вы просто перенаправите все запросы, которые не соответствуют файлу или каталогу, на /index.php
а затем прочтите URL из $_SERVER['REQUEST_URI']
. Вот как с этим справляются основные веб-приложения на основе PHP, такие как WordPress и MediaWiki.