本文记录了一次部署 API 接口的踩坑经历,写得不好,多多指教。😆😆
在写我的个人博客系统的时候,要开发一个评论小模块,其中有一项功能:有用户 1已经评论留言,用户 2在用户 1的评论下,给用户 1回复评论。
这时候需要发一封邮件通知用户 1的评论收到了回复,于是就利用「Nodemailer」写了这样一个功能,具体实现见JavaScript 利用Nodemailer发送电子邮件,使用Node.js编写,接口放在了云服务器上。
在本地服务器localhost:3000测试后,可以正常发送请求,并发送邮件。
但是当我将博客项目打包成静态页面,托管在腾讯云开发上后,再次测试,浏览器控制台(Edge)发出以下错误:
查了一下资料,发现原因是页面通过HTTPS加载,而发出的请求是HTTP协议的,这个请求被浏览器拦截,因此服务器没有收到请求。
于是我想把服务器的接口地址配置上SSL证书,也通过HTTPS协议访问,这样发送的请求也是HTTPS协议,应该就没问题了。
但经过一番尝试后,发现我只有一个博客域名,申请的SSL证书是绑定这个域名的,无法再绑定到IP地址,于是又失败了...🙃🙃🙃
既然只有一个域名,我又想到了一个方案:将博客部署到云服务器,域名解析到服务器,API 接口放在服务器的另一个端口,这样博客页面和 API 接口使用同一个域名(端口号不同),不就都可以配置SLL证书,都实现HTTPS协议了吗!😁
于是我把博客页面由腾讯云开发托管,改为部署到云服务器,并配置SSL证书,具体见nginx下安装SSL证书,为页面开启HTTPS访问!
然后修改了 API 接口,原 API 接口见JavaScript 利用Nodemailer发送电子邮件,修改了app.js,添加https模块来配置SSL证书:
const express = require('express');
const app = express();
const email = require('./email');
const https = require('https');
const fs = require('fs');
// 拦截所有请求
app.use((req, res, next) => {
// 1.允许哪些客户端访问我
// * 代表允许所有的客户端访问我
// 注意:如果跨域请求中涉及到cookie信息传递,值不可以为*号 比如是具体的域名信息
res.header('Access-Control-Allow-Origin', 'https://lzxjack.top');
// 2.允许客户端使用哪些请求方法访问我
res.header('Access-Control-Allow-Methods', 'get');
// 允许客户端发送跨域请求时携带cookie信息
res.header('Access-Control-Allow-Credentials', true);
next();
});
// 博客评论收到回复后的邮件提醒服务
app.use('/email', email);
const httpsOption = {
key: fs.readFileSync('./SSL/lzxjack.top.key'), //配置自己的证书
cert: fs.readFileSync('./SSL/lzxjack.top.pem'), //同上
};
https.createServer(httpsOption, app).listen(444);
console.log('服务器启动成功,监听444端口...');
客户端调用接口时,以https协议,并加上端口号444:
axios({
url: 'https://lzxjack.top:444/email',
method: 'get',
params: {
name,
owner,
email: replyEmail,
search: props.postTitle,
},
withCredentials: true,
})
这样就完成了!用户回复评论时,服务器可以正常收到请求,并发送提醒邮件!🚩🚩🚩