使用 NextJS + Express 在本地主机上使用 HTTPS

HTTPS on localhost using NextJS + Express

系统信息

目标

在本地主机上使用 SSL over HTTPS 服务 Web 应用程序

做了什么

  1. 使用 Create Next App
  2. 创建了基本的 NextJS 应用程序
  3. 使用 OpenSSL 生成证书和密钥并将其移至项目目录
  4. 添加了 Express 依赖项
  5. 将应用配置为在内部使用 express server.js
  6. 更改脚本以使用 package.json 脚本中的 server.js

server.js

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

const https = require('https');
const fs = require('fs');
const httpsOptions = {
  key: fs.readFileSync('./certificates/key.pem'),
  cert: fs.readFileSync('./certificates/cert.pem')
};

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

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

    server.listen(port, err => {
      if (err) throw err;
      console.log('> Ready on http://localhost: ' + port);
    });
  })
  .catch(ex => {
    console.error(ex.stack);
    process.exit(1);
  });

额外信息

该应用目前在使用 yarn dev 初始化时可以正常运行。我尝试使用 this answer 通过 https 提供应用程序,但我无法弄清楚如何使用 NextJS 将其应用到我当前的设置中。

我花了很多时间在网上研究如何应用这个解决方案,但还没有找到如何使它起作用的方法。

非常感谢任何帮助。

你只需要使用https模块的createServer方法即可。

const { createServer } = require('https');
const { parse } = require('url');
const { readFileSync } = require('fs');
const next = require('next');

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

const httpsOptions = {
  key: readFileSync('./certificates/key.pem'),
  cert: readFileSync('./certificates/cert.pem')
};

app.prepare()
  .then(() => {
    createServer(httpsOptions, (req, res) => {
      const parsedUrl = parse(req.url, true);
      handle(req, res, parsedUrl);
    }).listen(port, err => {
      if (err) throw err;
      console.log(`> Ready on https://localhost:${port}`);
    })
  });

其他答案似乎只是直接放弃...在服务器代码和证书都遇到一些困难后找到了解决方案,希望可以为其他人省去麻烦!

首先,在这里创建本地主机证书的可靠建议: https://letsencrypt.org/docs/certificates-for-localhost/

其次,简单的代码提供 HTTP/HTTPS 和下一个 js 并表达:

const next = require('next');
const express = require('express');
const http = require('http');
const https = require('https');
const fs = require('fs');

const ports = {
  http: 3080,
  https: 3443
}
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const server = express();  

const options = { 
  key: fs.readFileSync('localhost.key'),
  cert: fs.readFileSync('localhost.crt'), 
};

app.prepare().then(() => {           
  server.all('*', (req, res) => {
    return handle(req, res)    
  });
  http.createServer(server).listen(ports.http);
  https.createServer(options, server).listen(ports.https);
});

值得注意的是,可以省略或重定向任一端口。

下一个使用 https 的服务器非常适合我;​​

使用node js https模块的官方文档Creating HTTPS Server

const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const { readFileSync } = require('fs');

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

const httpsOptions = {
    pfx: readFileSync('./certificates/AMB.pfx'),
    passphrase: 'Testabc$'
  };

app.prepare().then(() => {
    createServer(httpsOptions, (req, res) => {    
        const parsedUrl = parse(req.url, true)
        const { pathname, query } = parsedUrl

        if (pathname === '/login') {
            app.render(req, res, '/login', query)
        } else {
            handle(req, res, parsedUrl)
        }
    }).listen(port, err => {
        if (err) throw err
        console.log(`> Ready on https://localhost:${port}`)
    })
})

我们直接的、可切换的实现:

const app = require('express')();
const https = require('https');
const http = require('http');
const next = require('next');
const fs = require('fs');
const path = require('path');

const HTTPS = true;
const server = HTTPS
  ? https.createServer(
      {
        key: fs.readFileSync(path.resolve(__dirname, './server.key')),
        cert: fs.readFileSync(path.resolve(__dirname, './server.cert')),
      },
      app
    )
  : http.createServer({}, app);

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const nextApp = next({ dev });
const nextHandler = nextApp.getRequestHandler();

nextApp.prepare().then(() => {
  app.get('/api/something', (req, res) => {
    res.json({});
  });

  // ...

  app.get('*', (req, res) => {
    return nextHandler(req, res);
  });

  server.listen(port, (err) => {
    if (err) throw err;
    console.log(`> Ready on http${HTTPS ? 's' : ''}://localhost:${port}`);
  });
});