Heroku 将 Next.js React 客户端应用程序 http 重定向到 https
Posted
技术标签:
【中文标题】Heroku 将 Next.js React 客户端应用程序 http 重定向到 https【英文标题】:Heroku redirect Next.js React client app http to https 【发布时间】:2019-11-13 01:29:17 【问题描述】:我在 Heroku 上部署了一个 express 服务器:https://server.mydomain.com
还有一个 Next.js React 应用也部署在 Heroku 上:https://app.mydomain.com
它们的 SSL 证书都由 Heroku 自动配置,当我访问 https 域时,它们按预期工作。
我遇到的问题是当我访问http://app.mydomain.com时,它没有重定向到https://app.mydomain.com。
我在网上找到的所有解决方案都指向在服务器上强制使用 SSL:
this popular question 表示要检查x-forwarded-proto
值:
/* At the top, with other redirect methods before other routes */
app.get('*',function(req,res,next)
if(req.headers['x-forwarded-proto']!='https')
res.redirect('https://app.mydomain.com'+req.url)
else
next() /* Continue to other routes if we're not redirecting */
)
和其他人建议使用express-sslify 或heroku-ssl-redirect 之类的包。
这些解决方案适用于服务器请求,但加载 React 客户端页面不一定会触发 app.get()
。显然,React 客户端可以独立于服务器运行。
所以问题是: 有人如何为 Heroku 上的子域 Next.js React 客户端应用强制 https?不使用快速服务器方法?
【问题讨论】:
你在为你的测功机付钱吗? 我有两个应用程序部署到 Heroku,一个在付费帐户上,一个在非付费帐户上。付费的会自动重新路由到 https,而免费的则不会。 是的。两者都是付费的。 你的 Procfile 是什么样的? 睡在上面,Obviously, a React client can run independently of a server.
伸出来。客户端需要服务器,heroku 很可能通过节点服务器(我认为这是默认的 Web 服务器)为您的静态文件夹提供服务。您需要做的是构建一个 express 应用程序来提供您的静态构建文件,并有一个 Procfile 告诉 heroku 针对该 express 应用程序而不是直接针对您的 react 应用程序运行节点。
【参考方案1】:
我在我的一个生产应用程序中执行此操作。
我们准备下一个应用程序对象并初始化一个快速服务器。这是在 server.js 文件中完成的。您可以在docs about a custom server 中了解更多信息。
Next.js 在其 github 的示例文件夹中也有一个关于自定义快速服务器的示例。我是here。
const express = require('express');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const app = next( dev );
const handle = app.getRequestHandler();
app
.prepare()
.then(() =>
const server = express();
server.use((req, res, next) =>
const hostname = req.hostname === 'www.app.domain.com' ? 'app.domain.com' : req.hostname;
if (req.headers['x-forwarded-proto'] === 'http' || req.hostname === 'www.app.domain.com')
res.redirect(301, `https://$hostname$req.url`);
return;
res.setHeader('strict-transport-security', 'max-age=31536000; includeSubDomains; preload');
next();
);
server.get('*', (req, res) => handle(req, res));
server.listen(
4242,
error =>
if (error) throw error;
console.error('Listening on port 4242');
);
)
.catch(error =>
console.error(error);
process.exit(1);
);
至于部署到 Heroku,您应该可以自定义 npm start 脚本来启动 nextjs,如下所示:
"scripts":
"dev": "next",
"build": "next build",
"start": "next start"
Heroku 还会自动运行 npm run build,因此它应该为您构建应用程序。
【讨论】:
在 Next.js 应用程序的上下文中,您将其具体放在哪里,以及如何部署 Heroku? @5tormTrooper 认为这很明显......我会更新答案 先生,您是一位绅士和一位学者。有效!感谢您花时间如此清晰地概述它。非常感激! ? @5tormTrooper 很高兴我能帮上忙 :) 有没有办法在不使用自定义服务器的情况下做到这一点?【参考方案2】:Heroku 目前不向force the use of https
for node apps“提供开箱即用”功能。
但是,随着 Nextjs v12 的发布,您无需设置 custom server 并改用 middleware 即可完成此操作。
参见this answer 的示例代码和middleware
与custom server
的优势。
我还发布了npm package 来处理这个问题:
import sslRedirect from 'next-ssl-redirect-middleware';
export default sslRedirect();
【讨论】:
以上是关于Heroku 将 Next.js React 客户端应用程序 http 重定向到 https的主要内容,如果未能解决你的问题,请参考以下文章
如何将带有 Mongodb 的 Next.js 应用程序部署到 Heroku?
Next.Js 带有样式组件的 React 应用程序。警告:道具 `className` 不匹配。服务器:“x” 客户端:“y”