我有一个简单的Express.js实例,该实例为单个页面Angular应用程序提供静态资产。我在Express配置上设置了一些中间件,以便为所有路由返回index.html,并且Angular可以从那里加载。
最近,我在Heroku上设置了SSL,并希望确保所有来自HTTP的流量都重定向到HTTPS。我想建议的解决方案相结合,从这个帖子有什么我现在有,但在一个无限重定向循环结束了。
简而言之,我需要将所有流量从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);
Heroku在负载均衡器级别终止SSL连接,因此req.secure永远不会成立,因为您到heroku的负载均衡器的连接未使用SSL,因此创建了无限重定向循环。
req.secure
您必须改为检查X-Forwarded-Proto标题:
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
app.enable("trust proxy")