Angular: перезагрузка / URL-навигация возвращается к маршруту по умолчанию

0

Я использую Angular 1.3.10, ui-router 0.2.10 и Express 4.14.0 для базового клона Reddit, и у меня возникают проблемы с маршрутизацией.

Мой (сокращенный) Экспресс-маршруты:

router.get('/api/home', function (req, res, next) {
  res.render('index', {
    title: 'Meanit'
  });
});

router.get('*', function (req, res, next) {
  res.redirect('/api/home');
});

Моя конфигурация углового состояния:

app.config([
  '$stateProvider',
  '$urlRouterProvider',
  '$locationProvider',
  function ($stateProvider, $urlRouterProvider, $locationProvider) {
    $stateProvider
      .state('home', {
        url: '/home',
        templateUrl: '/views/home.html',
        controller: 'MainCtrl',
        resolve: {
          postPromise: [
            'posts',
            function (posts) {
              return posts.getAllPosts();
            }
          ]
        }                      
      })
      .state('posts', {
        url: '/posts/{id}',
        templateUrl: '/views/posts.html',
        controller: 'PostsCtrl',
        resolve: {
          post: [
            '$stateParams',
            'posts',
            function ($stateParams, posts) {
              return posts.getPost($stateParams.id);
            }
          ]
        }
      })
      .state('register', {
        url: '/register',
        templateUrl: '/views/register.html',
        controller: 'AuthCtrl',
        onEnter: [
          '$state',
          'auth',
          function ($state, auth) {
            if (auth.isLoggedIn())
              $state.go('home')
          }
        ]
      })
      .state('login', {
        url: '/login',
        templateUrl: '/views/login.html',
        controller: 'AuthCtrl',
        onEnter: [
          '$state',
          'auth',
          function ($state, auth) {
            if (auth.isLoggedIn())
              $state.go('home')
          }
        ]
      });

    $locationProvider.html5Mode(true);
    $urlRouterProvider.otherwise('home');
  }
]);

Моя иерархия папок выглядит так:

meanit
  public
    js
      app.js (Angular)
  routes
    index.js (Express routes)
  views (Angular templates)
    index.html
    home.html
    posts.html
    register.html
    login.html
  server.js

Все маршруты работают по назначению, но когда я перезагружаю страницу на одном из маршрутов или перехожу непосредственно к URL-адресу маршрута (/posts/579d17934b0f5f6b2ff5c72c), я перенаправляюсь сначала в /api/home через Express (предполагается, я думаю), а затем в /home через Угловое вместо маршрута /posts/579d17934b0f5f6b2ff5c72c (НЕ предназначено).

Как заставить навигацию/перезагрузку URL оставаться на подпункте?

(Я посмотрел на AngularJS. Сохраняйте состояние после перезагрузки страницы, но я не понимаю, как настроить парсинг URL/как адаптировать код из принятого ответа в соответствии с моим проектом.)

  • 0
    Как вы справляетесь со своими статическими ресурсами (JavaScript, CSS, HTML, изображения и т. Д.)? Экспресс обслуживает их или вы используете другой веб-сервер, например, nginx?
  • 0
    Не слишком знаком с Express, но мне кажется, что вы не хотите, чтобы Express перенаправлял URL. Когда express отправляет вас в / api / home, angular не распознает его, потому что это не тот штат, в котором вы перечислены, поэтому вы попадаете в / home
Показать ещё 5 комментариев
Теги:
express
angular-ui-router

2 ответа

0
Лучший ответ

Кажется, ваша проблема с экспрессом. Ваш catchall делает res.redirect(), который, я думаю, обновляет URL-адрес браузера. Я предлагаю вам просто сделать простой sendfile() или render() вместо redirect().

Маршрут вашего экспресс-сервера должен измениться на:

//This is assuming the index.html file exists on the same directory the server is launched from
router.get('*', function (req, res, next) {
    res.render('index', {
        title: 'Meanit'
    });
});
  • 0
    Вы совершенно правы! Я изменил экспресс-маршрутизацию, чтобы использовать res.render напрямую вместо перенаправления обратно на маршрут / api / home, и теперь он работает отлично. Спасибо за вашу помощь!
  • 0
    Рад, что мы наконец нашли проблему, и вы можете приступить к созданию приложения.
0

У меня была аналогичная проблема, когда я начал один из моих проектов angularjs. В моем случае у меня было 2 разных сервера; один для API, а другой предназначен для обслуживания статических файлов. Вот как выглядит мой экспресс-статический сервер:

server.js

//server.js

var express = require('express');

var app = express();

//use very specific paths to the different resource folders
app.use('/js', express.static('public/js'));
app.use('/css', express.static('public/css'));
app.use('/img', express.static('public/img'));
app.use('/views', express.static('public/views'));
app.use('/bower_components', express.static('public/bower_components'));

var port = process.env.PORT || 80;
var staticExtensions = ['css','js','png','gif','jpg','woff','woff2','ttf','map'];
var deeperPaths = ['/posts']; //an array of deeper paths that need special treatment

//cater specifically for post, since it deeper than other paths (relative to the other assets /css, /js etc)
app.get('/posts/:postId', function(req,res){
    console.log('fetching matched request: '+ req.path + '...');
    res.sendFile(__dirname +'/public/index.html');
});

//any other request returns the index.html file, where angularjs routing takes over
app.get('*', function(req, res) {
    console.log('fetching '+ req.path + '...');
    var filePath = __dirname +'/public/index.html';

    var requestPath = req.path.split('?')[0];
    var fileExtension = requestPath.split('.').pop();
    //if it a static resource make relative to /public
    if(staticExtensions.lastIndexOf(fileExtension)>-1){
        deeperPaths.forEach(function(path, index){   
           //this is not a very reliable test, but it works for now  
           if(req.path.indexOf(path)===0){
               filePath = __dirname + '/public' + req.path.replace(path, '');
            }
        });
    }
    res.sendFile(filePath); // load our public/index.html file
});

// START THE SERVER
app.listen(port);
console.log('Website started on port ' + port);

Надеюсь это поможет...

  • 0
    К сожалению, мое приложение имеет ту же самую ловушку (с экспресс-маршрутизатором), и это не решает проблему. Я уверен, что это проблема Angular не сохранения состояния маршрута?
  • 0
    состояние не может существовать после перезагрузки всей страницы. Возможно, вы захотите проверить, используя вкладку сети инструментов Chrome Dev, чтобы убедиться, что сервер не возвращает неправильный контент. В моем собственном случае я заметил, что когда запрошенный URL-адрес на один шаг глубже, чем файл индекса (например, / posts / {id}), все мои статические ресурсы начинают возвращать содержимое файла index.html, что является запасным вариантом. Вот почему необходимо сопоставить конкретные пути для каждого типа ресурса.
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню