Angular маршрутизация не работает, когда URL-адрес напрямую посещается в браузере, но работает при нажатии на кнопку?

У меня есть приложение angular со структурой каталогов

app 
..views
....partials
......main.jade
......foo.jade
....index.jade

и маршруты, определенные как:

'использовать strict';

angular.module('myApp', [
  'ngCookies',
  'ngResource',
  'ngSanitize',
  'ngRoute', 
  'firebase', 
  'myApp.config'
])
  .config(function ($routeProvider, $locationProvider) {
    $locationProvider.html5Mode(true);  

    $routeProvider
      .when('/', {
        templateUrl: '/partials/main',
        controller: 'MainCtrl'
      })
      .when('/foo/:fooName', {
        templateUrl: '/partials/foo',
        controller: 'FooCtrl'
      })            
      .otherwise({
        redirectTo: '/'
      });
  });

Я использую express на стороне сервера, а соответствующий код:

    // server.js 
   app.configure('development', function(){
     app.use(express.static(path.join(__dirname, '.tmp')));
     app.use(express.static(path.join(__dirname, 'app')));
     app.use(express.errorHandler());
   });

   app.configure('production', function(){
    app.use(express.favicon(path.join(__dirname, 'public/favicon.ico')));
    app.use(express.static(path.join(__dirname, 'public')));
   });

    app.get('/', routes.index);
    app.get('/partials/:name', routes.partials);

    //routes.js
    exports.index = function(req, res){
      res.render('index');
    };


    exports.partials = function(req, res){
      var name = req.params.name;
      res.render('partials/' + name);
    };

Основной маршрут "/" загружается нормально, и когда я нажимаю на "/foo/bar", частичный вид foo.jade загружается, как ожидалось. Однако, когда я пытаюсь посетить "/foo/bar" прямо в URL-адресе, я получаю ответ 404 от Express "cannot GET /foo/bar", что имеет смысл, поскольку нет пути, подобного этому в выражении. Тем не менее, я думал, что это все, что нужно для определения маршрутизатора angular..i.e. он должен перехватить этот запрос и попросить "/partials/foo". Я попробовал добавить

//redirect all others to the index (HTML5 history)
app.get('*', routes.index);

но он не решил проблему и, похоже, улавливал даже запросы на статические js-активы и отвечал содержимым index.html, что довольно плохо. Я уверен, что я делаю что-то неправильно. Как я могу исправить вещи, чтобы я мог напрямую посещать URL-адреса?

Ответ 1

Причина, по которой происходит маршрутизация, выглядит так: html5mode включен. Обратите внимание на строку: $locationProvider.html5Mode(true);

Вам нужно понять, что, когда вы пытаетесь получить доступ к "/foo/bar", ваш браузер отправляет HTTP GET-запрос на этот URL-адрес. Когда вы пытаетесь получить доступ к этому URL-адресу по ссылке, как вы сказали, Angular перехватывает это действие и вызывает History.pushState, который обновляет только ссылку на браузер.

Что вам нужно сделать, чтобы сделать работу по маршрутизации html5mode, это внедрение перезаписи URL. Каждый запрос должен быть перенаправлен в ваш индексный файл, который загружает приложение AngularJS, но это необходимо сделать на вашем сервере. Angular сделает желаемую страницу самостоятельно.

Отметьте connect mod rewrite задачу grunt, которая делает это более подробно.

Вы также можете это промежуточное программное обеспечение.