Подтвердить что ты не робот

Режим AngularJS HTML5 - Как прямые ссылки работают без изменений на сервере?

Примечание. Этот вопрос также может быть прочитан:

Как поддерживать закладок безвредных клиентских сторон mvc-фреймворков в Java.

Я перехожу к приложению angular, использующему hashtags к html5mode. Я успешно установил

$locationProvider.html5Mode(true);

И все ссылки с целевой страницы (index.html) работают нормально.

Проблема в том, что если частичные URL-адреса ссылаются напрямую, я получаю 404, естественно, поскольку определения конечных точек сервера не связаны с определенными на стороне клиента маршрутами.

Таким образом, без HTML5 мы получаем не-SEO дружественные hashbangs, но с ним мы не можем добавлять закладки ничего, кроме целевой страницы (страница, которая загружается angular).

Почему это работает, если сначала запрашивать целевую страницу по умолчанию (index.html), то есть htpp://mydomain.com/:

  • Браузер запрашивает index.html с сервера
  • Сервер возвращает index.html, а браузер загружает angular framework
  • Изменения URL-адреса отправляются на клиентский маршрутизатор и загружаются соответствующие частичные /s.

Почему это не работает, если (т.е.) http://mydomain.com/foo запрашивается непосредственно из браузера:

  • Браузер запрашивает mydomain/foo с сервера.
  • Ресурс не существует
  • Сервер возвращает 404

Что-то не хватает в этой истории, я просто не знаю, что. Вот только два ответа, которые я вижу...

  • Это по дизайну. Как это работает? Пользователи должны всегда приземляться на странице начальной загрузки платформы MVC (обычно index.html), а затем перемещаться оттуда. Это не идеально, потому что состояние не может быть сохранено, и нет возможности закладки... не говоря уже об обходе.
  • Серверное решение.. Работает ли это с помощью уловки на стороне сервера? Например, по всем запросам верните index.html и сразу вызовите маршрутизатор с дополнительным контекстом. Если это так, это противоречит объекту, что AngularJS полностью на стороне клиента и кажется взломанным.
4b9b3361

Ответ 1

Документация AngularJS действительно упоминает об этом

Сторона сервера. В этом режиме требуется переписывание URL-адресов на стороне сервера, в основном вы должны переписать все свои ссылки на точку входа приложения (например, index.html)

В этом случае одно решение на основе Java должно сказать серверу "сопоставить все URL-адреса с index.html". Это можно сделать на любом HTTP-сервере или в контейнере. Я реализовал это с помощью Java/Servet, так как я хочу, чтобы мое приложение было агностическим сервером HTTP (например, Apache или NginX, или только Tomcat/JBoss).

В web.xml:

  <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <servlet>
      <servlet-name>StaticServlet</servlet-name>
      <jsp-file>/index.jsp</jsp-file>
  </servlet>

  <servlet-mapping>
      <servlet-name>StaticServlet</servlet-name>
      <url-pattern>/app</url-pattern>
  </servlet-mapping>

И index.jsp выглядит просто:

<%@ include file="index.html" %>

И добавьте следующее в тег в index.html:

<base href="/app" />

Ответ 2

Я некоторое время думал об этом для своего сайта PHP. Я держу весь код на стороне сервера с маршрутом /api, чтобы сохранить его отдельно от Angular. Вот решение, которое я придумал, обновив конфигурацию apache:

RewriteEngine on
#let the php framework do its thing
RewriteRule ^(api/.*)$ index.php?url=$1 [QSA,L,NC]
#let angular do its thing
RewriteCond %{REQUEST_FILENAME} !-f      
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.html [NC,L]

Я написал, как я это сделал, используя фреймворк Flight Framework на http://www.awnage.com/2013/10/10/taking-flight-with-angularjs/

Ответ 3

URL-адреса, на которые вы ссылаетесь, и помещаете их в адресную строку пользователя, должны ссылаться на допустимый контент на сервере, и, если это вообще возможно, они должны ссылаться на правильный контент. Конечно, вы можете просто обслуживать одну и ту же страницу для каждого URL-адреса, а клиентский код отключается и загружать реальный контент, и все работает так же, как в мире хеш-URL. Фактически, это способ наименьшего кода. Но он также квалифицируется как "взлом интернета", поэтому HTML5 и API истории предоставляют вам способ ссылки на семантически корректные URL-адреса.

В качестве небольшого примера, если вы перейдете к https://github.com/kriskowal/q, и вы нажмете "примеры", клиентский код загрузит "примеры" в браузере файлов, не выходя из страницы, а строка URL будет читать https://github.com/kriskowal/q/tree/master/examples. Если вы перейдете в https://github.com/kriskowal/q/tree/master/examples напрямую, вы получите содержимое каталога примеров, отправленное непосредственно в ваш браузер, без посредничества на стороне клиента, Да, это сложнее сделать и, возможно, невозможно в "приложении с одной страницей", но это правильно сделать в любое время, когда это возможно.