【问题标题】:HTTPS on localhost using NextJS + Express使用 NextJS + Express 在本地主机上进行 HTTPS
【发布时间】:2019-08-13 16:55:23
【问题描述】:

系统信息

目标

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

做了什么

  1. 使用Create Next App 创建了基本的 NextJS 应用程序
  2. 使用 OpenSSL 生成证书和密钥并将其移动到项目目录中
  3. 添加了 Express 依赖项
  4. 将应用配置为在 server.js 中使用 express
  5. 将脚本更改为在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 将其应用于我当前的设置。

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

非常感谢任何帮助。

【问题讨论】:

    标签: reactjs express https localhost next.js


    【解决方案1】:

    你只需要使用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}`);
        })
      });
    

    【讨论】:

    • 这对我有用,谢谢@Tibi02!以前我尝试使用createServer 方法,但我没有正确使用它,所以我很高兴你能给我一个很好的例子。
    • 快递在哪里?
    【解决方案2】:

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

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

    其次,提供 HTTP/HTTPS 和 next js 和 express 的简单代码:

    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);
    });
    

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

    【讨论】:

      【解决方案3】:

      以下对我来说非常适合使用 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}`)
          })
      })
      

      【讨论】:

        【解决方案4】:

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

        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}`);
          });
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-08-17
          • 1970-01-01
          • 2023-02-25
          • 2018-09-13
          • 1970-01-01
          • 2019-03-12
          • 1970-01-01
          • 2015-09-20
          相关资源
          最近更新 更多