5

我正在使用 Express 4 在我的后端托管我的 AngularJS 应用程序,并使用 Nginx 作为我的前端服务器。但是 html5 模式似乎不起作用,因为当我尝试http://localhost/login通过浏览器输入页面链接(例如)时,我会收到一个 Cannot /GET 错误。我需要为我的 Express/Nginx 做任何路由配置吗?这是我的配置代码:

快递4:

var express = require('express'),
    app = express(),
    server = require('http').Server(app),
    bodyParser = require('body-parser'),
    db = require('./db'),
    io = require('./sockets').listen(server),
    apiRoutes = require('./routes/api'),
    webRoutes = require('./routes/web');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));
app.use('/api', apiRoutes);
app.use(express.static(__dirname + '/public'));

server.listen(3000, function() {
  console.log('Listening on port %d', server.address().port);
});

AngularJS:

'use strict';
var nodeApp = angular.module('nodeApp',['ngRoute']);

nodeApp.config(function($routeProvider, $locationProvider, $controllerProvider) {
  $routeProvider.when('/', {
    templateUrl: 'partials/home.html'
  }).when('/login', {
    templateUrl: 'partials/login.html'
  });
  $locationProvider.html5Mode(true);

  nodeApp.controllerProvider = $controllerProvider;
});

Nginx:

# the IP(s) on which your server is running
upstream test-app {
  server 127.0.0.1:3000;
}

# the nginx server instance
server {
  listen 0.0.0.0:80;
  server_name test-app.cloudapp.net;
  access_log /var/log/nginx/test-app.log;

  # pass the request to the nodejs server with correct headers
  location / {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Nginx-Proxy true;

    proxy_pass http://test-app/;
    proxy_redirect off;
  }
}
4

1 回答 1

20

我假设您使用的是“单页”角度应用程序,因此一个使用 ng-view 加载所有其他部分的 html 页面。

在这种情况下,您需要执行以下操作:

快递4:

var express = require('express'),
    app = express(),
    server = require('http').Server(app),
    bodyParser = require('body-parser'),
    db = require('./db'),
    io = require('./sockets').listen(server),
    apiRoutes = require('./routes/api'),
    webRoutes = require('./routes/web');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
  extended: true
}));
app.use('/api', apiRoutes);
app.use(express.static(__dirname + '/public'));
// Here's the new code:
app.use('/*', function(req, res){
  res.sendfile(__dirname + '/public/index.html');
});

server.listen(3000, function() {
  console.log('Listening on port %d', server.address().port);
});

您面临的问题是,即使您在触发路由之前为“/login”设置了路由,也需要加载它们。因此,服务器尝试为无法返回 404 的路由“/login”找到匹配项。在单页角度应用程序的情况下,您在路由中使用的所有路由都必须被路由捕获,app.get('/*', ...在这种情况下,然后返回主 angular.js html 页面。请注意,这是最后一次调用,所以它会被最后评估,如果你把它放在第一位,它将阻止所有后续规则运行,因为 express 只运行它遇到的第一个规则的处理程序。

于 2014-08-11T03:52:09.310 回答