简体   繁体   English

在根上表达命名占位符路由

[英]Express named placeholder routes on root

I'm currently building a MEAN app and I have routing setup as you'd expect (/login, /profile, /logout etc).我目前正在构建一个 MEAN 应用程序,并且按照您的预期进行了路由设置(/login、/profile、/logout 等)。 I've come to the point now in my app where I'm building user profile pages and I'd like user profiles to be accessible from the root of the domain, like: www.domain.com/:username .我现在已经在我的应用程序中构建用户配置文件页面,并且我希望用户配置文件可以从域的根目录访问,例如: www.domain.com/:username

I currently have the following route which is defined at the end of my routes.js file and just before my catchall/wildcard routes.我目前有以下路由,它在我的 routes.js 文件末尾和我的 catchall/wildcard 路由之前定义。

app.get('/:username', function (req, res) {
    var username = req.params.username;
        usersTable.findOne({ 'local.username': username }, function (err, user) {               
            if (err)
                return err;

            if (!user)
                res.redirect('/');

            res.render('public-profile.ejs', {
                user: user
            });
        });
});

app.all('/*', function (req, res, next) {
    if (req.user) {
        res.sendfile('views/dashboard.html'); // for angular routing
    } else {
        res.redirect('/login');
    }
});

As it currently stands there is some interference between Express/Angular.目前的情况是 Express/Angular 之间存在一些干扰。 If I visit /matthew which is a username and then try to load /profile from the URL bar, Angular doesn't catch this (/* route) and instead loads the default ('/') angular route.如果我访问 /matthew 这是一个用户名,然后尝试从 URL 栏加载 /profile,Angular 不会捕获这个(/* 路由)而是加载默认的('/')角度路由。

My concern is that I wouldn't be able to create a /:username route in Angular because how will that page know what user data to show?我担心的是我无法在 Angular 中创建 /:username 路由,因为该页面如何知道要显示哪些用户数据? Will I have to create an API call that reads the given URL which then looks for a user in the database with that name?我是否必须创建一个 API 调用来读取给定的 URL,然后在数据库中查找具有该名称的用户? (seems clunky?) (看起来笨重?)

I'm pretty new to building large-scale webapps so advice on the architecture would be great.我对构建大型 web 应用程序还很陌生,所以对架构的建议会很棒。

The code in your post only configures the server-side routes, which has in fact nothing to do with Angular routing.您帖子中的代码仅配置了服务器端路由,实际上与Angular路由无关。

Angular is for single-page applications (SPA). Angular 适用于单页应用程序 (SPA)。 If you want to use AngularJS on the client, you probably don't want to serve pages from the server, but return data, ie your routes are meant for API calls only.如果您想在客户端使用 AngularJS,您可能不想从服务器提供页面,而是返回数据,即您的路由仅用于 API 调用。

So, on the client-side, you should have something like :所以,在客户端,你应该有类似的东西:

myApp
.constant('MY_BACKEND_URL', 'http://www.domain.com')
.config(['$stateProvider', function ($stateProvider) { // client-side route config

  $stateProvider
    .state('userProfile',{
    url: '/:username',
    templateUrl: 'views/user-profile.html',
    controller: 'UserProfileCtrl',
    resolve: { // lets you resolve asynchronously before page is loaded.
      userData: ['$http', 'MY_BACKEND_URL', '$stateParams', '$state', function ($http, MY_BACKEND_URL, $stateParams, $state) {
        return $http
          .get(MY_BACKEND_URL + '/' + $stateParams.username)// returns a promise of the user data fetch from the API.
          .catch(function (err) {
            $state.go('dashboard');
          });
      }]
    }
  });

  $stateProvider.state('dashboard',{
    url: '/',
    template: 'views/dashboard.html',
    controller: 'DashboardCtrl'
  });
}]);

And on the server side :在服务器端:

// config route for API call to user resource 
app.get('/user/:username', function (req, res) {
  var username = req.params.username;
  usersTable.findOne({ 'local.username': username }, function (err, user) {
    if (err) {
      res.json(500, err);
    } else if (!user) {
      res.json(404, {reason: "No such username", username: username});
    } else {
      res.json(200, user);
    }
  });
});

As a rule of thumb, routes on the client-side (Angular) configure pages, whereas routes on the server-side configure your API, ie endpoints you call for fetching data.根据经验,客户端 (Angular) 上的路由配置页面,而服务器端的路由配置您的 API,即您调用以获取数据的端点。

By the way, you should remove the return err;顺便说一句,您应该删除return err; statement from your callback, because there is no point in returning a value from a callback function that is meant for side-effects only.从回调中声明,因为从仅用于副作用的回调函数返回值是没有意义的。 You probably want to replace it with something like :您可能想用以下内容替换它:

if(err){
  res.json(500, err); // return internal server error response.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM