Назад | Перейти на главную страницу

Перенаправление Apache на тот же путь, но с # фрагментом

Я бы хотел добавить #fragment чтобы клиент мог читать определенные URL-адреса (и используемые SPA).

<IfModule mod_rewrite.c>
 RewriteEngine On
 RewriteBase /
 RewriteRule ^foo/? /foo#bar [QSA,NE,L,R=301]
</IfModule>

Однако, поскольку #bar является фрагментом в приведенном выше URL-адресе, кажется, что он удален и вызывает цикл перенаправления. Я также пытался избежать хеша, например RewriteRule ^foo/? /foo\#bar.

Есть ли способ ограничить это RewriteRule всего на одно перенаправление?

Вы не можете. Фрагменты обрабатываются только браузером. Они никогда не передаются на сервер.

Я также пытался избежать хеша, например ...

Проблема не в ответе на перенаправление. /foo#bar правильно отправляется обратно клиенту в Location: заголовок ( NE флаг помогает здесь, предотвращая # кодируется URL-адресом в ответе).

Проблема в том, что браузер не отправляет идентификатор фрагмента обратно на сервер на перенаправлен запрос (как заявил @Gerald: «[Фрагменты] никогда не передаются на сервер»). Так что сервер неоднократно видит /foo, отсюда и цикл перенаправления. Вы ничего не можете поделать с отсутствующим идентификатором фрагмента.

С точки зрения сервера вам нужно будет изменить URL-адрес каким-либо другим способом, например, добавив параметр строки запроса. Например:

RewriteCond %{QUERY_STRING} !^redirect
RewriteRule ^foo/? /foo?redirect=1#bar [QSA,NE,R,L]

Вышеупомянутое добавляет redirect=1 Параметр URL для ответа на перенаправление, и условие гарантирует, что этот параметр отсутствует перед выполнением перенаправления.

Однако добавление параметра URL-адреса, вероятно, нежелательно.

Поскольку это предназначено только для использования клиентом в SPA, вместо этого вы должны использовать API истории JavaScript и replaceState() (или возможно pushState()) метод (ы) для добавления #bar идентификатор фрагмента в URL-адрес и вызовет ответ на стороне клиента. Перенаправление на стороне сервера не требуется.