Удаление идентификатора фрагмента из URL-адресов AngularJS (символ #)


257

Можно ли удалить символ # из URL angular.js?

Я все еще хочу иметь возможность использовать кнопку назад браузера и т. Д., Когда я изменяю представление и обновляю URL с помощью params, но мне не нужен символ #.

Учебник routeProvider объявлен следующим образом:

angular.module('phonecat', []).
  config(['$routeProvider', function($routeProvider) {
  $routeProvider.
  when('/phones', {templateUrl: 'partials/phone-list.html',   controller: PhoneListCtrl}).
  when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
  otherwise({redirectTo: '/phones'});
}]);

Могу ли я изменить это, чтобы иметь такую ​​же функциональность без #?


13
хороший хэштег
BoJack Всадник


Для меня все ответы здесь неверны. Мы можем «переписать» URL-адрес и удалить #, но никогда не получим прямой доступ к веб-странице без #. Любое реальное решение здесь ???
amdev

Вот решение, если вы используете Angular 1.6 .
Мисталис

Ответы:


251

Да, вы должны настроить $locationProviderи набор html5Modeдля true:

angular.module('phonecat', []).
  config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {

    $routeProvider.
      when('/phones', {templateUrl: 'partials/phone-list.html',   controller: PhoneListCtrl}).
      when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
      otherwise({redirectTo: '/phones'});

    $locationProvider.html5Mode(true);

  }]);

10
Потому что IE lt 10 не поддерживает html5 history API, которые были включены при настройке html5Mode(true). В IE вы должны использовать #в маршрутах.
Максим Грач,

10
@powtac IE lt 10означает Internet Explorer меньше, чем версия 10
Максим Грач

6
Можете ли вы установить его так, чтобы это отступило от использования # в IE? Это так просто , как только обертывание $locationProvider.html5Mode(true);в if !(IE lt 10)?
Энди Хейден

52
Таким образом, это решение решает проблему удаления хэштега в URL, учитывая, что у URL есть хэштег, однако он не решает, как отвечать на запросы, которые не хотят, чтобы хэштег был включен в первую очередь. Ака, он решает бла / # / Телефоны -> бла / телефоны, но он не обрабатывает бла / телефоны напрямую.
Люк

9
Мне нужно было поместить <base href = "/" /> в мой раздел index.html <head>.
nyxz

55

Обязательно проверьте поддержку браузером API истории html5:

  if(window.history && window.history.pushState){
    $locationProvider.html5Mode(true);
  }

23
Это может быть лучше подходит для комментариев, так как не дает прямого ответа на вопрос.
brandonscript

31
Согласно руководству разработчика , это обнаружение выполняется автоматически:If the HTML5 History API is not supported by a browser, the $location service will fall back to using the hashbang URLs automatically
IanB

Работал как шарм, и я ценю проверку методов, а не проверку версий браузера - будущее.
Шейн

46

Чтобы удалить хеш-тег для красивого URL-адреса, а также чтобы ваш код работал после минимизации, вам необходимо структурировать свой код, как показано в следующем примере:

jobApp.config(['$routeProvider','$locationProvider',
    function($routeProvider, $locationProvider) {
        $routeProvider.
            when('/', {
                templateUrl: 'views/job-list.html',
                controller: 'JobListController'
            }).
            when('/menus', {
                templateUrl: 'views/job-list.html',
                controller: 'JobListController'
            }).
            when('/menus/:id', {
                templateUrl: 'views/job-detail.html',
                controller: 'JobDetailController'
            });

         //you can include a fallback by  including .otherwise({
          //redirectTo: '/jobs'
        //});


        //check browser support
        if(window.history && window.history.pushState){
            //$locationProvider.html5Mode(true); will cause an error $location in HTML5 mode requires a  tag to be present! Unless you set baseUrl tag after head tag like so: <head> <base href="https://stackoverflow.com/">

         // to know more about setting base URL visit: https://docs.angularjs.org/error/$location/nobase

         // if you don't wish to set base URL then use this
         $locationProvider.html5Mode({
                 enabled: true,
                 requireBase: false
          });
        }
    }]);

15
За requireBase: false+1
whoan

2
Здравствуйте @digitlimit, после добавления $locationProvider.html5Modeкода мой код $urlRouterProvider.otherwise('/home');перестал работать.
Jaikrat

18

Я выписываю правило в web.config после того, $locationProvider.html5Mode(true)как задано в app.js.

Надеюсь, выручит кого-то.

  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
          </conditions>
          <action type="Rewrite" url="/" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>

В моем index.html я добавил это в <head>

<base href="/">

Не забудьте установить переписчик URL для iis на сервере.

Также, если вы используете Web Api и IIS, этот URL-адрес совпадения не будет работать, так как он изменит ваши вызовы API. Поэтому добавьте третий вход (третья строка условия) и укажите шаблон, который исключает вызовы изwww.yourdomain.com/api


1
Как установить переписчик URL для IIS? Я хостинг на Azure.
Прабху

11

Если вы находитесь в стеке .NET с MVC с AngularJS, это то, что вам нужно сделать, чтобы удалить '#' из URL:

  1. Настройте ваш базовый href на странице _Layout: <head> <base href="https://stackoverflow.com/"> </head>

  2. Затем добавьте следующее в конфигурацию вашего углового приложения: $locationProvider.html5Mode(true)

  3. Выше удалит «#» из URL, но обновление страницы не будет работать, например, если вы находитесь на странице «yoursite.com/about», обновление даст вам 404. Это потому, что MVC не знает об угловой маршрутизации и по шаблону MVC это будет искать страницу MVC для 'about', которой нет в пути маршрутизации MVC. Обходным путем для этого является отправка всех запросов страниц MVC в одно представление MVC, и вы можете сделать это, добавив маршрут, который перехватывает все

URL:

routes.MapRoute(
    name: "App",
    url: "{*url}",
    defaults: new {
        controller = "Home", action = "Index"
    }
);

В какой файл я должен добавить маршруты .MapRoute?
Вичеанак

1
RouteConfig.cs его в папке App_Start
Максуд

5

Вы можете настроить режим html5, но он работает только для ссылок, включенных в привязки html вашей страницы, и того, как URL-адрес выглядит в адресной строке браузера. Попытка запросить подстраницу без хэштега (с или без html5mode) из любой точки за пределами страницы приведет к ошибке 404. Например, следующий запрос CURL приведет к ошибке «страница не найдена» независимо от html5mode:

$ curl http://foo.bar/phones

хотя следующее вернет корневую / домашнюю страницу:

$ curl http://foo.bar/#/phones

Причина этого заключается в том, что все, что находится после хэштега, удаляется до того, как запрос поступит на сервер. Таким образом, запрос http://foo.bar/#/portfolioна сервер поступает как запрос на http://foo.bar. Сервер ответит ответом 200 OK (предположительно), http://foo.barа агент / клиент обработает остальное.

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


Нет ли способа обойти это? Это довольно большая проблема.
user441521

5

Выполните 2 шага:
1. Сначала установите $ locationProvider.html5Mode (true) в файле конфигурации вашего приложения.
Например, -
angular.module('test', ['ui.router']) .config(function($stateProvider, $urlRouterProvider, $locationProvider) { $locationProvider.html5Mode(true); $urlRouterProvider.otherwise('/'); });

2. Во-вторых, установите <base> внутри вашей главной страницы.
Например, ->
<base href="https://stackoverflow.com/">

Служба $ location автоматически переключится на метод hash-part для браузеров, которые не поддерживают API истории HTML5.


3

Мое решение - создать .htaccess и использовать #Sorian код .. без .htaccess мне не удалось удалить #

RewriteEngine   On
RewriteBase     /
RewriteCond     %{REQUEST_URI} !^(/index\.php|/img|/js|/css|/robots\.txt|/favicon\.ico)
RewriteCond     %{REQUEST_FILENAME} !-f
RewriteCond     %{REQUEST_FILENAME} !-d
RewriteRule     ./index.html [L]

1

Согласно документации. Ты можешь использовать:

$locationProvider.html5Mode(true).hashPrefix('!');

Примечание: если ваш браузер не поддерживает HTML 5. Не беспокойтесь: D у него есть запасной вариант в режиме hashbang. Таким образом, вам не нужно проверять if(window.history && window.history.pushState){ ... }вручную

Например: если вы нажмете: <a href="https://stackoverflow.com/other">Some URL</a>

В браузере HTML5 : angular автоматически перенаправит наexample.com/other

В не HTML5-браузере : angular автоматически перенаправит наexample.com/#!/other


1

В этом ответе предполагается, что вы используете nginx в качестве обратного прокси-сервера и уже установили для $ locationProvider.html5mode значение true.

-> Для людей, которые все еще могут бороться со всеми классными вещами выше.

Конечно, @maxim grach solution работает отлично, но для решения того, как реагировать на запросы, которые не хотят, чтобы хэштег был включен в первую очередь, можно проверить, отправляет ли php 404, а затем переписать URL. Ниже приведен код для nginx,

В местоположении php, обнаружите ошибку 404 php и перенаправьте в другое место,

location ~ \.php${
  ...
  fastcgi_intercept_errors on;
  error_page 404 = /redirect/$request_uri ;
}

Затем перепишите URL в месте перенаправления и proxy_pass данные, конечно же, поместите URL вашего сайта вместо URL моего блога. (Запрос: вопрос только после того, как вы попробовали)

location /redirect {
  rewrite ^/redirect/(.*) /$1;
  proxy_pass http://www.techromance.com;
}

И увидеть магию.

И это определенно работает, по крайней мере для меня.


Где это добавить?
Volatil3

Где добавить код выше? Поместите их в основной файл конфигурации Nginx.
Сатис

1

Начать с index.html удалить все #из <a href="#/aboutus">About Us</a>так оно должно выглядеть <a href="https://stackoverflow.com/aboutus">About Us</a>.Теперь в голове тега index.html записи <base href="https://stackoverflow.com/">только после последнего мета - тег .

Теперь в вашей маршрутизации JS внедрить $locationProviderи написать $locatonProvider.html5Mode(true); что-то вроде этого: -

app.config(function ($routeProvider, $locationProvider) {
    $routeProvider
        .when("/home", {
            templateUrl: "Templates/home.html",
            controller: "homeController"
        })
            .when("/aboutus",{templateUrl:"Templates/aboutus.html"})
            .when("/courses", {
                templateUrl: "Templates/courses.html",
                controller: "coursesController"
            })
            .when("/students", {
                templateUrl: "Templates/students.html",
                controller: "studentsController"
            })
        $locationProvider.html5Mode(true);
    });

Для получения дополнительной информации смотрите это видео https://www.youtube.com/watch?v=XsRugDQaGOo.


Удаление всего # Url помогло, потому что я тестировал его, не удаляя #urls.
optimistanoop

1

Думаю, это действительно поздно для этого. Но добавление приведенного ниже конфига в импорт app.module делает работу:

RouterModule.forRoot(routes, { useHash: false })

0

Шаг 1. Вставьте службу $ locationProvider в конструктор конфигурации приложения.

Шаг 2. Добавьте строку кода $ locationProvider.html5Mode (true) в конструктор конфигурации приложения.

Шаг 3: на странице контейнера (лендинг, мастер или макет) добавьте HTML-тег, например, <base href="https://stackoverflow.com/">внутри тега.

Шаг 4: удалите все «#» для маршрутизации конфигурации из всех тегов привязки. Например, href = "# home" становится href = "home"; href = "# about" становится herf = "about"; href = "# contact "становится href =" контакт "

 <ul class="nav navbar-nav">
     <li><a href="home">Home</a></li>
     <li><a href="about">About us</a></li>
     <li><a href="contact">Contact us</a></li>
</ul>

-1

Просто добавьте $locationProviderв

.config(function ($routeProvider,$locationProvider)

а затем добавить $locationProvider.hashPrefix(''); после

.otherwise({
        redirectTo: '/'
      });

Вот и все.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.