目录
文末提供了完整思路,供大家继续推进,已经写了六千字了不想写了😂
本文技术概要:
- html文件修改:利用ai工具已经获得了本地的html文件,但该html文件是将数据保存在浏览器当中。发布到互联网,需要将数据保存到本地文件夹当中,在html文件中修改
- node.js网页部署:如果自家路由器不涉及CGNAT技术,则到此步骤即可互联网访问自己的网页;否则必须进行内网穿透
- 路由器虚拟化服务器:将互联网的端口开放,便于成功访问
- 内网穿透技术:家庭宽带运营商为了节省IP地址,会使用一种叫做 “运营商级NAT” (CGNAT) 的技术,使得电脑公网ip与实际公网ip不同,无法直接通过公网ip访问
本文按照一边实验一边操作思路,如果你发现已经部署成功,则不用关注后续操作
核心问题:为什么不能直接分享HTML文件?
刚编写好的网页,只能通过双击html文件采用浏览器打开,所有数据都存储在浏览器的
localStorage
里。这意味着:
A用户在A电脑上打开,数据存在A电脑的浏览器里。
B用户在B电脑上访问同一个HTML文件,他的数据存在B电脑的浏览器里。 他们的数据是完全独立、互不可见的。
为了让大家能看到对方的数据,进行网页的互动,就必须把数据从各个用户的浏览器里抽出来,统一存放在一个地方——你的电脑。你的电脑将扮演“服务器”的角色。
1,html文件修改
打开你的index.htm文件,去掉将数据保存到localStorage的操作,而是通过网络请求,与后续步骤设置的server.js后台进行通信
如果你已经设置好了上述步骤,则不用修改文件;如果你一头雾水,则照着下列步骤直接做一遍。
打开index文件,搜索loadState,然后使用下列代码替换原本的loadState代码块和saveState代码块。
// 新的 loadState 函数
loadState() {
fetch('/api/data')
.then(response => response.json())
.then(savedData => {
if (savedData) { this.state.data = savedData; }
if (!this.state.data.completedMilestones) { this.state.data.completedMilestones = []; }
if (!this.state.data.activityLog) { this.state.data.activityLog = []; }
const todayData = this.state.data[this.state.today]?.checkedTasks || [];
this.todaySelections = new Set(todayData);
// 加载完数据后,立即渲染一次页面
this.render();
})
.catch(error => {
console.error("加载数据失败:", error);
// 即使加载失败,也要保证基本结构存在
if (!this.state.data.completedMilestones) { this.state.data.completedMilestones = []; }
if (!this.state.data.activityLog) { this.state.data.activityLog = []; }
this.render();
});
},
// 新的 saveState 函数
saveState(isSilent = false) {
if (!this.state.data[this.state.today]) {
this.state.data[this.state.today] = { checkedTasks: [], messages: [] };
}
this.state.data[this.state.today].checkedTasks = Array.from(this.todaySelections);
fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(this.state.data)
})
.then(response => response.json())
.then(result => {
console.log(result.message); // 在控制台打印 "数据保存成功"
if (!isSilent) { alert('今日记录已保存!'); }
})
.catch(error => {
console.error("保存数据失败:", error);
if (!isSilent) { alert('保存失败,请检查服务器连接!'); }
});
},
代码解释:新的loadState
在页面加载时会去/api/data
这个地址获取数据。新的saveState
则会把整个this.state.data
对象打包成JSON格式,发送到/api/data
地址,由server.js
接收并存入db.json
文件。
2,安装设置node.js
先安装node工具,然后创建后台服务器,并确保将node服务器打开
访问 Node.js官网。
安装对应自己电脑的版本,和普通软件安装过程一致。
Win+R输入cmd,在终端中输入:node -v 可以查看是否安装成功
在你希望保存文件的位置创建文件夹checkin-server,在文件夹中放入自己写的index.html
同目录下创建文本文档,命名为server.js ,文本编辑器打开,复制以下代码:
// 引入我们需要的工具包
const express = require('express');
const fs = require('fs');
const path = require('path');
// 创建一个应用实例
const app = express();
const PORT = 3000; // 网页的访问端口号,可以保持不变
const DB_FILE = path.join(__dirname, 'db.json'); // 数据库文件的路径
// 中间件,用于解析发送到服务器的JSON格式数据
app.use(express.json());
// 中间件,用于提供index.html等静态文件
app.use(express.static(__dirname));
// --- API 接口 ---
// 1. 获取数据的接口 (GET)
app.get('/api/data', (req, res) => {
if (fs.existsSync(DB_FILE)) {
fs.readFile(DB_FILE, 'utf8', (err, data) => {
if (err) {
return res.status(500).json({ message: '读取数据失败' });
}
res.json(JSON.parse(data));
});
} else {
// 如果文件不存在,返回一个空的初始结构
res.json({ completedMilestones: [], activityLog: [] });
}
});
// 2. 保存数据的接口 (POST)
app.post('/api/data', (req, res) => {
const dataToSave = req.body;
fs.writeFile(DB_FILE, JSON.stringify(dataToSave, null, 2), 'utf8', (err) => {
if (err) {
return res.status(500).json({ message: '保存数据失败' });
}
res.json({ message: '数据保存成功' });
});
});
// 启动服务器
app.listen(PORT, () => {
console.log(`服务器已启动,正在监听 http://localhost:${PORT}`);
});
代码解释:这个文件创建了一个小型的Web服务器。它会把当前文件夹作为网站的根目录(所以能找到index.html
),并创建了两个URL:/api/data
的GET请求用来读取数据,POST请求用来写入数据。我们的“数据库”就是一个名为 db.json
的文件。
接下来启动node:
win+R,输入cmd进入终端。切换工作目录到checkin-server目录中
如果发现终端无法切换到D盘,E盘,则只需要输入图片中对应的指令,用到的指令如下:
#切换到E盘
e:
#切换到D盘
d:
#切换到对应目录,使用cd命令
cd checkin-server
在对应目录的终端中输入:
node server.js
此时node.js就启动成功了,我们已经可以在本地访问自己的html文件。在浏览器中输入:http://localhost:3000
即可直接访问到自己的html网页
但这远远不够,我们希望可以让互联网上的其他人,也能够访问到这个网页来。
3,路由器虚拟服务器
本节进行路由器设置,开放我们的网页到互联网,或者局域网上面。
打开电脑浏览器,输入192.168.1.1,进入路由器登陆界面。输入密码,登陆进入系统。密码就在自家路由器的背面,会写客户端密码
选择应用管理,找到虚拟服务器(有的也叫端口设置),进入,并添加新规则
如图添加规则内容,端口都设置为3000,ip地址填写本地ip地址,协议选择tcp
本地ip地址获取方法1:打开终端,输入ipconfig(Linux输入ifconfig),我连接的wifi,因此看wifi一栏,如果是路由器则看以太网配置器
本地ip地址获取方法2:通过网络中心来看
到这里配置好之后,确保node.js处于运行状态,此时就一定可以局域网访问了。
局域网访问方法:
多台设备连接到同一个wifi……只要是同一个路由器,都可以直接通过 http://192.168.1.xxx:3000访问到,中间的数字是IP地址,根据自己电脑的来。
互联网访问方法:
互联网访问需要获得本电脑的公网ip才行,通过公网ip进行。打开浏览器,搜索我的ip,选择第一个进入,就可以看到以下页面:
这里的IP和本地电脑ip不同,这里就是公网ip。不出意外,其他人在浏览器搜索: http://xxx.192.xxx.170:3000 就可以访问到你的网页。
出意外了:可能是防火墙问题,也可能是运营商问题。
如果你的运营商采用了CGNAT技术,则不可直接访问,以下方式可以确认是否采用。在路由器操作端,查看上网设置,发现本机ip为10.x.x.x或者100.x.x.x ,就是和公网ip不同,那百分之百采用了CGNAT技术,就必须采取内网穿透技术来让其他人通过互联网访问了。
但如果你发现是一样的,且你确定你的运行商没有采用CGNAT技术,也可能是防火墙的问题。搜索防火墙,打开Windows Defender 防火墙,进入高级设置
设置入站规则,开放端口3000入站
需要为你电脑的防火墙添加入站规则,允许3000
端口的连接:
对于 Windows 系统:
按
Win
键,搜索“高级安全的 Windows Defender 防火墙”并打开。在左侧点击“入站规则”。
在右侧点击“新建规则...”。
选择“端口”,点击“下一步”。
选择“TCP”,然后在“特定本地端口”里输入
3000
,点击“下一步”。选择“允许连接”,点击“下一步”。
将“域”、“专用”、“公用”三个选项都勾选上,点击“下一步”。
给规则起个名字,比如
NodeServerPort
,然后点击“完成”。
之后再访问 http://xxx.192.xxx.170:3000 就可以了,注意中间的IP地址为公网ip,不是本地ip
4,采用ngrok工具进行内网穿透(国外工具)
打开该网页,登录会要求必须注册,获取个人认证码。
下载windows版本,并将下载的zip文件解压,将.exe文件复制到checkin-server文件夹当中。打开终端,切换到checkin-server目录,粘贴下载页面的这段代码,该代码为认证代码:
<token>部分为注册登陆后自动生成。复制粘贴到终端中运行完成之后,输入 ngrok http 3000开放端口渗透
ngrok http 3000
从运行结果中可以看到, https://36bc14c962e8.ngrok-free.app ,该链接极为访问到我们网页的链接。将该链接发送给其他人,其他人就可以访问到。
存在的问题:
- 由于ngrok是国外的工具,因此他自动选择最近的服务器是日本的,因此不挂梯子,可能进不去网页
- 每次重启ngrok之后,该链接都会变化。交钱注册会员,可以获得固定的二级域名,会员价格每个月三四块钱
因此,我们可以采用国内的内网穿透工具,有很多,这里只是拿NETAPP举例。
5,采用natapp工具进行内网穿透(国内工具)
打开网站 https://natapp.cn/ 。也是必须先注册,后使用
可以直接点击购买隧道,免费隧道,然后进行配置3000端口,获取自己的Authtoken,这相当于自己的登录密码
注册完成后,下载客户端,将natapp.exe文件放到checkin-server文件夹当中,打开终端,执行下列命令,激活自己的账号:
natapp -authtoken=你的authtoken字符串
然后输入natapp,即可成功运行该穿透工具。
natapp
之后复制http://xxxx.natappfree.cc 给自己的朋友,即可成功访问。同样每次打开natapp工具,网址都不一样,这样不好。花钱注册可以获得固定的二级域名。(就是不想花钱,才想把自己的电脑作为服务器的…………)
我没有进行详细的操作,因为国内的网站总是要求进行身份认证,因此我到这一步就停止了。考虑到花钱获得固定域名,以及由于CGNAT技术的存在我必须在后台同时打开node.js的窗口,内网穿透的窗口,因此我打算购买云服务器进行网页配置了。
6,更多思路(来自大神:kcbpmbf)
一、针对常规的内网穿透工具,不能固定域名,固定域名需要付费:
有大内网,可以采用樱花frp,他最早是搞二次元的,当年的樱花签到就可以领流量
二、节点小宝蒲公英
其实你还有另一条路 就是用随时可以连进内网的工具 叫什么节点小宝 蒲公英。你在内网部署完以后 你在任意设备任意外网都可以用软件连接进你的内网 然后使用你的服务 这种隐私性高
三、飞牛
还有更简单的 你在你电脑上用虚拟机也好还是用啥 反正你建个飞牛os 然后在飞牛里用docker建站 然后白嫖飞牛的免费端口映射出来 下行3mb/s。还能有nas服务。他等于说免费给你提供端口映射嘛。免费的自带的,它本身飞牛就是个NAS系统,为了方便你这个外网下载文件给你提供的
四、我的方案
我的解决方案是,这个,这个拿台工控机装个PVe,然后里边装上软路由儿,然后去拿光猫拨号,拨号上网,然后获取公网IP。我这个是真正的公共IP。他那个公共IP呀,是老变的,但是有个服务叫DDNS。我就拿那个爱快动态域名服务给绑定上我的域名儿,然后域名儿就是死的,他IP再怎么变,我通过域名就能访问。这也是一条路子,但现在好像运营商申请公共IP挺费劲。比如说,你要是这个方便迁移的服务,那我觉得你用飞牛挺好的,对吧?飞牛里边儿docker还能随时迁移,随时备份
五、更好的办法。相比采用自己的电脑作为服务器
采用vercel,免费且个人项目很很够用,或者使用cloudflare