我在Heroku上有一个使用create-react-app
创建的应用程序。就在今天,我使用Heroku的自动(-ish)SSL证书流程ExpeditedSSL获得了SSL证书,然后文档建议将所有http请求重新路由到https。
我有一个server.js文件并表达我只是试图运行中间件然后提供我的React应用程序。
我知道SSL证书的工作就好像我去https://myapp.com我看到了我的Heroku应用程序,但当我转到http://myapp.com时,它没有被重定向到我的Heroku应用程序的https版本。< / p>
我今天已经从StackOverflow,Google和其他方面尝试了很多很多solutions
,并且这些解决方案都没有为我工作。我也没有收到任何错误。它只是没有用。
尝试使用https library
:
const https = require("https");
const express = require('express');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
https.createServer(app).listen(3000);
使用heroku-ssl-redirect
的另一次尝试:
var sslRedirect = require('heroku-ssl-redirect');
var express = require('express');
var app = express();
// enable ssl redirect
app.use(sslRedirect(['production'], 301));
app.use(express.static(path.join(__dirname, 'build')));
app.get('*', (req, res, next) => {
if (req.headers['x-forwarded-proto'] != 'https'){
res.redirect('https://' + req.hostname + req.url);
} else {
next();
}
});
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(process.env.PORT || 3000);
尝试使用x-forward-proto
:
const express = require('express');
const env = process.env.NODE_ENV || 'development';
const bodyParser = require('body-parser');
const path = require('path');
const app = express();
var forceSsl = function (req, res, next) {
if (req.headers['x-forwarded-proto'] !== 'https') {
return res.redirect(['https://', req.get('Host'), req.url].join(''));
}
return next();
};
if (env === 'production') {
app.use(forceSsl);
}
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(process.env.PORT || 8080);
我还尝试过各种博客和SO帖子中的一些随机节点安装,但没有任何效果。没有任何错误,我很难弄清楚为什么这不起作用。
答案 0 :(得分:1)
尝试将以下内容添加到index.html文件的标题
<script>
var host = "www.URL.com" || "URL.com";
if ((host == window.location.host) && (window.location.protocol != "https:")){
window.location.protocol = "https";
}
</script>
我正在处理类似的问题,这让我可以解决它。将它放在标题中可确保脚本在任何捆绑的JavaScript之前运行,但我认为它可以在您的bundle.js文件之上运行
答案 1 :(得分:1)
以下更新和安全的解决方案:
因为您正在使用create-react-app通过Heroku部署React应用,并且它是buidlpack(如果不是,则建议使用:create-react-app-buildpack)。因此,正如官方文档所说:
Web服务器可能是configured via the static buildpack。
配置文件static.json
应该在存储库的根目录下提交。如果此文件位于子目录中,则不会被识别
如果仓库中不存在默认的static.json
,则为:
{
"root": "build/",
"routes": {
"/**": "index.html"
}
}
通过自动将不安全的请求重定向到static.json
中的 https:// :
{
"root": "build/",
"routes": {
"/**": "index.html"
},
"https_only": true
}
@misterfoxy的方法有效,但方法不正确!
答案 2 :(得分:0)
尝试使用express-https-redirect
。
安装时:
npm install express-https-redirect --save
然后你应该可以做类似的事情:
const express = require('express');
const httpsRedirect = require('express-https-redirect');
const app = express();
app.use('/', httpsRedirect());
app.set('port', process.env.PORT || 3000);
app.use(express.static(path.join(__dirname, 'build')));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
答案 3 :(得分:0)
尝试将其添加到index.html文件中 将其放在标头中,这样它将在其他脚本之前运行
<script>
const domain1 = "www.example.com";
const domain2 = "example.com";
const host = window.location.host;
if ((domain === host || domain2 === host) && (window.location.protocol !== "https:")){
window.location.href = "https://www.example.com";
}
</script>