AngularJS - 处理手动输入URL的最佳方式

时间:2014-10-10 22:46:17

标签: javascript node.js angularjs express meanjs

我目前有一个基于meanjs堆栈样板的设置,我可以让用户登录这种“登录”状态,因为我浏览网站的URL。这是因为将用户对象保留在全局可用的服务中。

然而,只有当我从我的基地导航时,这才有效,即从'/'导航,并仅在我的应用中导航。

如果我手动输入诸如'/ page1'之类的URL,它会丢失全局用户对象,但是如果我转到我的根主页并通过该站点导航到'/ page1'。然后没关系,它会在Service对象中看到全局用户对象。

所以我猜这是因为整页刷新失去了全局值,在这里通过网站导航不会刷新,所以你保留了所有的变量。

有些注意事项:

  1. 我启用了HTML5Mode,使用前缀'!'。
  2. 我使用UI-Router
  3. 我使用标签'/'
  4. 我在快递上有一个重写规则,在加载所有路由之后,我有一个最后一个路由,它接收所有'/ *'并发回root index.html文件,因为这是angularjs的东西是
  5. 我只是想知道人们一般在这做什么?他们是否还原标准cookie和本地存储解决方案?我对角度很新,所以我猜这里有图书馆。

    我只是想知道推荐的方法来处理这个问题或大多数人做什么,这样我就会以正确的方式和角度方式对齐。

    更新

    如果我通过地址栏手动导航到我网站上的其他网址,我会失去用户状态,但是如果我通过地址栏手动返回我的根目录,我的用户状态会再次显示,所以不是简单的关于窗口刷新失去状态。所以它似乎与在根URL上运行的代码有关。

    我有一个明确的重写,手动输入的URL(由于HTML5位置模式)应首先返回index.html,因为它包含AngularJs文件,然后UI-Route接管并正确路由它。

    所以我原本预计root上的任何代码都会执行,所以它应该类似于通过网站导航或输入地址栏。我一定错过了有关Angular的东西。

    更新2

    对,所以更多的调查引导我这样做:

    <script type="text/javascript">
        var user = {{ user | json | safe }};
    </script>
    

    这是index.html的服务器端代码,我想通过手动网址将页面刷新到新页面时不会运行。

    使用哈希爆炸模式,它可以工作,这是因为使用哈希爆炸模式,即使我在浏览器中键入URL,它也不会导致刷新,在使用HTML5模式时,它会刷新。所以现在我能想到的解决方案是使用sessionStorage。

    除非有更好的选择吗?

    更新3:

    使用HTML5Mode时,处理此问题的最佳方法是,您只需要在快速服务器上重写一些内容,然后再进行其他操作。

2 个答案:

答案 0 :(得分:1)

我认为你做得对,但你可能想看看你的应用可能需要的所有路线,并考虑一些基本结构(api,用户,会话,部分等)。它似乎就像其中一个问题那样复杂,你想让它成为现实。

就最佳做法而言,您可以按照angular-fullstack-generatormeanio项目进行操作。

你在做什么看起来最接近mean.io主要是因为他们也使用ui-router,虽然他们似乎保留了hashbang,看起来更像是一个SEO友好的一些独立的SPA页面能力。 您可以安装它并在我在此解释之前找到代码 -

npm install -g meanio
mean init name
cd [name] && npm install

angular-fullstack看起来像这样,这是更典型的路由的一个很好的例子:

// Server API Routes
app.route('/api/awesomeThings')
  .get(api.awesomeThings);

app.route('/api/users')
  .post(users.create)
  .put(users.changePassword);
app.route('/api/users/me')
  .get(users.me);
app.route('/api/users/:id')
  .get(users.show);

app.route('/api/session')
  .post(session.login)
  .delete(session.logout);

// All undefined api routes should return a 404
app.route('/api/*')
  .get(function(req, res) {
    res.send(404);
});

// All other routes to use Angular routing in app/scripts/app.js
app.route('/partials/*')
  .get(index.partials);
app.route('/*')
  .get( middleware.setUserCookie, index.index);

然后为了简单起见,使用一些正则表达式找到partials,并且不进行渲染,如下所示:

var path = require('path');

exports.partials = function(req, res) {
 var stripped = req.url.split('.')[0];
 var requestedView = path.join('./', stripped);
 res.render(requestedView, function(err, html) {
   if(err) {
     console.log("Error rendering partial '" + requestedView + "'\n", err);
     res.status(404);
     res.send(404);
   } else {
     res.send(html);
   }
 });
};

呈现索引:

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

答案 1 :(得分:1)

最后我确实遇到了很多麻烦但是设法通过做一些可以分解为步骤的事情来实现它,这些步骤适用于那些使用HTML5Mode的人。

1)在Angular中启用HTML5Mode后,在服务器上设置重写,以便它返回包含Angular src js文件的index.html。请注意,此重写应位于静态文件和普通服务器路由之后(例如,在REST API路由之后)。

2)确保角度路由与服务器路由不同。因此,如果您有一个前端状态/用户/帐户,那么没有服务器路由/用户/帐户,否则它将不会被调用,将服务器端路由更改为/ api / v1 / server / route。

3)对于前端中的所有锚标签,无需通过Angular状态/路由即可触发对服务器的直接调用,请确保添加&#39靶= _self&#39;