如何强制或重定向我的 next.js 网站以使用 https

jan*_*an 6 ssl https redirect next.js

我认为这将是一个简单的任务,但我很难找到一种方法来强制我的网页使用 https。next.js Web 应用程序位于 heroku 服务器上,我已经设置了 SSL。https 和 http 版本都可以,但如何强制或重定向网站以使用 https 版本。我见过一些使用express的解决方案,但我的网络应用程序中没有任何内容使用express,这是必需的吗?谢谢。

NSj*_*nas 26

从 Nextjs v12 开始,您可以使用中间件而不是设置自定义服务器

中间件是更好的解决方案,原因如下:

  • 自定义服务器通常需要额外的依赖项(例如express)
  • 你放弃了一些盒子功能,比如自动静态优化
  • 中间件可以使用内置的路由范例将范围扩展到特定路径

创建一个/pages/_middleware.ts(或.js)文件,其内容与此类似:

import  { NextFetchEvent, NextRequest, NextResponse } from 'next/server'

type Environment = "production" | "development" | "other";
export function middleware(req: NextRequest, ev: NextFetchEvent) {
    const currentEnv = process.env.NODE_ENV as Environment;

    if (currentEnv === 'production' && 
        req.headers.get("x-forwarded-proto") !== "https") {
        return NextResponse.redirect(
           `https://${req.headers.get('host')}${req.nextUrl.pathname}`,
           301
        );
    } 
    return NextResponse.next();
}
Run Code Online (Sandbox Code Playgroud)

我还为此创建了一个 npm 包

import sslRedirect from 'next-ssl-redirect-middleware';
export default sslRedirect({});
Run Code Online (Sandbox Code Playgroud)

  • @NSjonas 我在 Heroku 上托管 — 一个带有自动配置 SSL 的自定义域。这是我的项目中间件文件的链接:https://github.com/caleb531/faith-dashboard/blob/master/pages/_middleware.ts (3认同)
  • 使用这个解决方案给我带来了无限的重定向。问题是 `req.headers.get("x-forwarded-proto") !== "https")` 总是评估为 true,因为标头评估为 `"https,http"`。修改提供的解决方案以使用 `.indexOf("https") !== -1` 修复了此问题。 (2认同)

Nic*_*s D 4

有一个带有 NPM 库的解决方案,称为heroku-ssl-redirect.

首先,使用安装库npm i heroku-ssl-redirect

server.js然后,使用以下脚本创建一个新文件。

const next = require('next');
const express = require('express');
const sslRedirect = require('heroku-ssl-redirect').default; // to make it work with 'require' keyword.

const PORT = process.env.PORT || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  const server = express();

  // Express's middleware to automatically redirect to 'https'.
  server.use(sslRedirect());

  server.all('*', (req, res) => {
    return handle(req, res);
  });

  server.listen(port, err => {
    if (err) throw err;

    console.log(`Server starts on ${PORT}.`);
  });
});
Run Code Online (Sandbox Code Playgroud)

然后,将start脚本更改为如下所示:

"scripts": {
  "dev": "next",
  "build": "next build",
  "start": "node server.js"
}
Run Code Online (Sandbox Code Playgroud)

它应该有效。

请注意,您可以将 Express 替换createServer为原生 Node.jshttp模块中的方法。但我使用 Express 来简化语法。

进一步阅读:如何在 Next.js 中设置自定义服务器