Express.js重定向到HTTPS并发送index.html

时间:2015-10-05 15:18:30

标签: javascript angularjs node.js express heroku

我有一个简单的Express.js实例,它为单页Angular应用程序提供静态资源。我在Express配置上设置了一些中间件,以便为所有路由返回index.html,Angular可以从那里加载。

最近,我在Heroku上设置了SSL,我想确保从HTTP传入的所有流量都重定向到HTTPS。我试图将this post中建议的解决方案与我现在的解决方案结合起来,但最终会在无限的重定向循环中结束。

简而言之,我需要将所有流量从HTTP重定向到HTTPS,并为所有请求发送index.html文件。我在这里做错了什么?

var gzippo = require('gzippo');
var express = require('express');
var morgan = require('morgan');
var app = express();

// set environment variables
var env = app.get('env') || 'development';

app.use(morgan('dev'));

// serve static assets
app.use(gzippo.staticGzip("" + __dirname + "/dist"));
app.use("/js", express.static(__dirname + "/dist/scripts"));
app.use("/fonts", express.static(__dirname + "/fonts"));
app.use("/img", express.static(__dirname + "/dist/assets/images"));
app.use("/css", express.static(__dirname + "/dist/styles"));


// Redirect all HTTP traffic to HTTPS
function ensureSecure(req, res, next){
  if(req.secure){
    // OK, continue
    return next();
  };
  res.redirect('https://'+req.hostname+req.url); // handle port numbers if you need non defaults
};


// Always send index.html
function sendIndex(req, res, next) {
  res.sendfile('index.html', { root: __dirname + "/dist/"});
}


// Handle environments
if (env == 'production') {
  app.all('*', ensureSecure);
}

app.all('/*', sendIndex);

// Start server
app.listen(process.env.PORT || 5000);

1 个答案:

答案 0 :(得分:21)

Heroku在负载均衡器级别终止SSL连接,因此req.secure永远不会成为现实,因为您与heroku的负载均衡器的连接不使用SSL,因此会创建无限重定向循环。

您必须检查X-Forwarded-Proto标题:

if(req.headers["x-forwarded-proto"] === "https"){
  // OK, continue
  return next();
};
res.redirect('https://'+req.hostname+req.url);

修改:您还可以设置app.enable("trust proxy")以自动快速检查标题。见http://expressjs.com/guide/behind-proxies.html