Скрытые возможности mod_rewrite

Это то, что называется назначением деструктуризации , и это новая функция JavaScript 1.7 ECMAScript 6 ) (В настоящее время только доступный в JavaScript-движке FireFox.) Грубо говоря, это будет означать следующее:

var ActionButton = require("sdk/ui/button/action").ActionButton;

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

{x, y} = foo;

Является эквивалентом:

x = foo.x;
y = foo.y;

Это также можно использовать для массивов , Например, вы можете легко заменить два значения без использования временной переменной:

var a = 1;
var b = 3;

[a, b] = [b, a];

Поддержка браузера можно отслеживать с помощью таблицы совместимости kangax 'ES6 .

119
задан 5 revs, 3 users 100% 3 May 2012 в 14:57
поделиться

6 ответов

Куда поместить правила mod_rewrite

mod_rewrite, правила могут быть помещены в httpd.conf файл, или в .htaccess файл. если у Вас будет доступ к [1 114], то помещение правил здесь предложит выигрыш в производительности (поскольку правила обрабатываются однажды, в противоположность каждому разу .htaccess, файл называют).

Вход mod_rewrite запросы

Вход может быть включен из httpd.conf файл (включая [1 117]):

# logs can't be enabled from .htaccess
# loglevel > 2 is really spammy!
RewriteLog /path/to/rewrite.log
RewriteLogLevel 2

случаи Общего использования

  1. Для направления всех запросов к единственной точке:

    RewriteEngine on
    # ignore existing files
    RewriteCond %{REQUEST_FILENAME} !-f   
    # ignore existing directories
    RewriteCond %{REQUEST_FILENAME} !-d   
    # map requests to index.php and append as a query string
    RewriteRule ^(.*)$ index.php?query=$1 
    

    Начиная с Apache 2.2.16 можно также использовать FallbackResource .

  2. Обработка 301/302 перенаправления:

    RewriteEngine on
    # 302 Temporary Redirect (302 is the default, but can be specified for clarity)
    RewriteRule ^oldpage\.html$ /newpage.html [R=302]  
    # 301 Permanent Redirect
    RewriteRule ^oldpage2\.html$ /newpage.html [R=301] 
    

    Примечание : внешние перенаправления являются неявно 302 перенаправлениями:

    # this rule:
    RewriteRule ^somepage\.html$ http://google.com
    # is equivalent to:
    RewriteRule ^somepage\.html$ http://google.com [R]
    # and:
    RewriteRule ^somepage\.html$ http://google.com [R=302]
    
  3. SSL

    RewriteEngine on
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://example.com/$1 [R,L]
    
  4. Принуждения Общие флаги:

    • [R] или [redirect] - вызывают перенаправление (значения по умолчанию к 302 временным перенаправлениям)
    • [R=301], или [redirect=301] - вызывают 301 постоянное перенаправление
    • [L], или [last] - прекращают переписывать процесс (см. примечание ниже в распространенных ошибках)
    • [NC] или [nocase] - указывают, что соответствие должно быть нечувствительно к регистру


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

    можно разделить несколько флагов с запятой:

    RewriteRule ^olddir(.*)$ /newdir$1 [L,NC]
    

Распространенные ошибки

  1. Смешивание mod_alias стиль перенаправляет с [1 128]

    # Bad
    Redirect 302 /somepage.html http://example.com/otherpage.html
    RewriteEngine on
    RewriteRule ^(.*)$ index.php?query=$1
    
    # Good (use mod_rewrite for both)
    RewriteEngine on
    # 302 redirect and stop processing
    RewriteRule ^somepage.html$ /otherpage.html [R=302,L] 
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    # handle other redirects
    RewriteRule ^(.*)$ index.php?query=$1                 
    

    Примечание : можно смешаться mod_alias с [1 130], но это включает больше работы, чем просто обработка основных перенаправлений как выше.

  2. Контекст влияет на синтаксис

    В [1 131] файлы, ведущая наклонная черта не используется в шаблоне RewriteRule:

    # given: GET /directory/file.html
    
    # .htaccess
    # result: /newdirectory/file.html
    RewriteRule ^directory(.*)$ /newdirectory$1
    
    # .htaccess
    # result: no match!
    RewriteRule ^/directory(.*)$ /newdirectory$1
    
    # httpd.conf
    # result: /newdirectory/file.html
    RewriteRule ^/directory(.*)$ /newdirectory$1
    
    # Putting a "?" after the slash will allow it to work in both contexts:
    RewriteRule ^/?directory(.*)$ /newdirectory$1
    
  3. [L] не является последним! (иногда)

    Эти [L] остановки по требованию, обрабатывающие дальше, переписывают правила для этого, проходят через набор правила . Однако, если URL был изменен в той передаче, и Вы находитесь в .htaccess контекст или эти <Directory> раздел, затем Ваш измененный запрос будет пасуемым назад через механизм парсинга URL снова. И на следующей передаче, это может соответствовать другому правилу на этот раз. Если Вы не понимаете это, это часто похоже на Ваш [L], флаг не имел никакого эффекта.

    # processing does not stop here
    RewriteRule ^dirA$ /dirB [L] 
    # /dirC will be the final result
    RewriteRule ^dirB$ /dirC     
    

    Наш переписывать журнал показывает, что правила выполняются дважды, и URL обновляется дважды:

    rewrite 'dirA' -> '/dirB'
    internal redirect with /dirB [INTERNAL REDIRECT]
    rewrite 'dirB' -> '/dirC'
    

    лучший способ вокруг этого состоит в том, чтобы использовать [END] флаг (, видят документы Apache ) вместо эти [L] флаг, если Вы действительно хотите остановить всю последующую обработку правил (и последующие передачи). Однако эти [END] флаг только доступен для [1 185] Apache v2.3.9 + , поэтому если у Вас есть v2.2 или ниже, Вы застреваете только с эти [L] флаг.

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

    # Only process the following RewriteRule if on the first pass
    RewriteCond %{ENV:REDIRECT_STATUS} ^$
    RewriteRule ...
    

    Или необходимо удостовериться, что RewriteRule находятся в контексте (т.е. httpd.conf), который не заставит запрос быть повторно проанализированным.

203
ответ дан 7 revs, 6 users 74% 4 May 2012 в 01:57
поделиться

Другие подводные камни:

1- Иногда полезно отключить MultiViews

Options -MultiViews

Я не очень хорошо разбираюсь во всех возможностях MultiView, Предположим, у вас есть 2 файла php в вашем веб-каталоге, file1.php и file2.php, и вы добавляете эти условия и правило в свой .htaccess:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ file1.php/$1 

Вы предполагаете, что все URL-адреса, которые не соответствуют файлу или каталогу, будут захвачены Автор file1.php. Сюрприз! Это правило не соблюдается для URL http: // myhost / file2 / somepath . Вместо этого вы попадаете внутрь file2.php.

Что происходит, так это то, что MultiViews автоматически угадали, что на самом деле вам нужен URL-адрес http: //myhost/file2.php/somepath , и с радостью перенаправили вас туда.

Итак, вы понятия не имеете, что только что произошло, и в этот момент подвергаете сомнению все, что, как вы думали, вы знали о mod_rewrite. Затем вы начинаете экспериментировать с правилами, пытаясь понять логику этой новой ситуации, но тем более вы повторное тестирование имеет меньший смысл.

Хорошо, короче говоря, если вы хотите, чтобы mod_rewrite работал способом, приближенным к логике, отключение MultiViews - это шаг в правильном направлении.

2- включить FollowSymlinks

Options +FollowSymLinks 

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

13
ответ дан 24 November 2019 в 01:48
поделиться

Еще одна замечательная функция - это расширения rewrite-map. Они особенно полезны, если вам нужно обработать огромное количество хостов / перезаписей:

Они похожи на замену ключа-значения:

RewriteMap examplemap txt:/path/to/file/map.txt

Затем вы можете использовать сопоставление в своих правилах, например:

RewriteRule ^/ex/(.*) ${examplemap:$1}

Подробнее по этой теме можно найти здесь:

http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#mapfunc

3
ответ дан 24 November 2019 в 01:48
поделиться

Сделка с RewriteBase:

Вам почти всегда нужно устанавливать RewriteBase. Если вы этого не сделаете, apache предположит, что ваша база - это физический путь к вашему каталогу на диске. Итак, начните с этого:

RewriteBase /
18
ответ дан 24 November 2019 в 01:48
поделиться

Уравнение может быть сделано с помощью следующего примера:

RewriteCond %{REQUEST_URI} ^/(server0|server1).*$ [NC]
# %1 is the string that was found above
# %1<>%{HTTP_COOKIE} concatenates first macht with mod_rewrite variable -> "test0<>foo=bar;"
#RewriteCond search for a (.*) in the second part -> \1 is a reference to (.*)
# <> is used as an string separator/indicator, can be replaced by any other character
RewriteCond %1<>%{HTTP_COOKIE} !^(.*)<>.*stickysession=\1.*$ [NC]
RewriteRule ^(.*)$ https://notmatch.domain.com/ [R=301,L]

Динамическая балансировка нагрузки:

Если вы используете Mod_Proxy, чтобы сбалансировать свою систему, можно добавить динамический диапазон рабочего сервера.

RewriteCond %{HTTP_COOKIE} ^.*stickysession=route\.server([0-9]{1,2}).*$ [NC]
RewriteRule (.*) https://worker%1.internal.com/$1 [P,L]
5
ответ дан 24 November 2019 в 01:48
поделиться

если вам нужно «заблокировать» внутренние перенаправления / перезаписи, происходящие в .htaccess, обратите внимание на условие

RewriteCond %{ENV:REDIRECT_STATUS} ^$

, как обсуждается здесь .

21
ответ дан 24 November 2019 в 01:48
поделиться
Другие вопросы по тегам:

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