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

Posted

技术标签:

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

系统信息

Express:4.16.4 NextJS:8.0.3 React:16.8.4 ReactDOM:16.8.4

目标

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

做了什么

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

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

非常感谢任何帮助。

【问题讨论】:

【参考方案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`);
  );
);

【讨论】:

以上是关于使用 NextJS + Express 在本地主机上进行 HTTPS的主要内容,如果未能解决你的问题,请参考以下文章

NextJS,Express,WebSocket 握手期间出错:意外响应代码:200

NextJS vs Express [关闭]

Router.push 没有重定向我; Nextjs 与 Express 服务器

在server.js中获取301重定向数据(Express / NextJS)

如何使用 npm 并发包同时运行 Nextjs 应用程序和 Express 服务器?

如何在 NextJS 应用程序中从 Apollo 链接上下文访问 Express HTTP 请求?