Angular:重新加载/ URL导航将恢复为默认路由

时间:2016-07-30 22:28:13

标签: javascript angularjs node.js express angular-ui-router

我使用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');
});

My Angular状态配置:

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)时,我首先通过Express重定向到/ api / home (打算,我认为)然后通过Angular而不是/ posts / 579d17934b0f5f6b2ff5c72c路由(不打算)到/ home。

如何强制网址导航/重新加载以保持在子路径上?

(我已查看AngularJS. Retain state after page reload,但我不了解如何设置网址解析/如何根据接受的答案调整代码以适合我的项目。)

2 个答案:

答案 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's 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's 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);

希望这会有所帮助......

答案 1 :(得分: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'
    });
});