为Hexo博客启用HTTPS协议

为Hexo博客启用HTTPS协议

前言

随着HTTP协议的越来越不被待见,以及各大浏览器厂商对于HTTP采取的打压措施,举个栗子,当我在服务器上同时启用HTTP以及HTTPS监听的时候,访问HTTP服务的时候,就会被重定向到HTTPS的链接上,但是HTTPS的链接又不存在,然后就会出现如下报错:

话不多说,我们直接上代码 server.js
server.js文件位于博客目录/node_modules/hexo-server/lib/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
'use strict';

const connect = require('connect');
const http = require('http');
const { underline } = require('picocolors');
const Promise = require('bluebird');
const open = require('open');
const net = require('net');
const https = require("https");
const fs = require("fs");

module.exports = function(args) {
const app = connect();
const { config } = this;
const ip = args.i || args.ip || config.server.ip || undefined;
const port = parseInt(args.p || args.port || config.server.port || process.env.port, 10) || 4000;
const { root } = config;

return checkPort(ip, port).then(() => this.extend.filter.exec('server_middleware', app, {context: this})).then(() => {
if (args.s || args.static) {
return this.load();
}

return this.watch();
}).then(() => startServer(http.createServer(app), port, ip)).then(server => {
const addr = server.address();
const addrString = formatAddress(ip || addr.address, addr.port, root);

this.log.info('Hexo is running at %s . Press Ctrl+C to stop.', underline(addrString));
this.emit('server');

if (args.o || args.open) {
open(addrString);
}

return server;
}).catch(err => {
switch (err.code) {
case 'EADDRINUSE':
this.log.fatal(`Port ${port} has been used. Try other port instead.`);
break;

case 'EACCES':
this.log.fatal(`Permission denied. You can't use port ${port}.`);
break;
}

this.unwatch();
throw err;
});
};

function startServer(server, port, ip) {
return new Promise((resolve, reject) => {
server.listen(port, ip, resolve);
server.on('error', reject);
}).then(() => server);
}

function checkPort(ip, port) {
if (port > 65535 || port < 1) {
return Promise.reject(new RangeError(`Port number ${port} is invalid. Try a number between 1 and 65535.`));
}

const server = net.createServer();

return new Promise((resolve, reject) => {
server.once('error', reject);
server.once('listening', resolve);
server.listen(port, ip);
}).then(() => { server.close(); });
}

function formatAddress(ip, port, root) {
let hostname = ip;
if (ip === '0.0.0.0' || ip === '::') {
hostname = 'localhost';
}

let path = root.startsWith("/") ? root : `/${root}`;
return new URL(`http://${hostname}:${port}${path}`).toString();
}

注意事项

  • 需要添加2个新的引用,分别是httpsfshttps用来创建https Serverfs用来读取证书信息:
    1
    2
    const https = require("https");
    const fs = require("fs");
  • 添加一个新的变量,options,用来存放证书:
    1
    2
    3
    4
    const options = {
    key:fs.readFileSync("$PWD/5792506_www.majun.fun.key"),
    cert:fs.readFileSync("$PWD/5792506_www.majun.fun.pem")
    };
  • 最后我们只需要创建一个https的服务器就可以了:
    1
    https.createServer(options, app).listen(443);