本地windows电脑部署html网页到互联网:html+node.js+ngrok/natapp

目录

核心概念:为什么不能直接分享HTML文件?

1,html文件修改

2,安装设置node.js

3,路由器虚拟服务器

4,采用ngrok工具进行内网穿透(国外工具)

5,采用natapp工具进行内网穿透(国内工具)


文末提供了完整思路,供大家继续推进,已经写了六千字了不想写了😂

本文技术概要:

  1. html文件修改:利用ai工具已经获得了本地的html文件,但该html文件是将数据保存在浏览器当中。发布到互联网,需要将数据保存到本地文件夹当中,在html文件中修改
  2. node.js网页部署:如果自家路由器不涉及CGNAT技术,则到此步骤即可互联网访问自己的网页;否则必须进行内网穿透
  3. 路由器虚拟化服务器:将互联网的端口开放,便于成功访问
  4. 内网穿透技术:家庭宽带运营商为了节省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代码块。

html 复制代码
// 新的 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 ,文本编辑器打开,复制以下代码:

javascript 复制代码
// 引入我们需要的工具包
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盘,则只需要输入图片中对应的指令,用到的指令如下:

bash 复制代码
#切换到E盘
e:

#切换到D盘
d:

#切换到对应目录,使用cd命令
cd checkin-server

在对应目录的终端中输入:

bash 复制代码
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 系统:

  1. Win 键,搜索"高级安全的 Windows Defender 防火墙"并打开。

  2. 在左侧点击"入站规则"。

  3. 在右侧点击"新建规则..."。

  4. 选择"端口",点击"下一步"。

  5. 选择"TCP ",然后在"特定本地端口 "里输入 3000,点击"下一步"。

  6. 选择"允许连接",点击"下一步"。

  7. 将"域"、"专用"、"公用"三个选项都勾选上,点击"下一步"。

  8. 给规则起个名字,比如 NodeServerPort,然后点击"完成"。

之后再访问 http://xxx.192.xxx.170:3000 就可以了,注意中间的IP地址为公网ip,不是本地ip

4,采用ngrok工具进行内网穿透(国外工具)

Download ngrok

打开该网页,登录会要求必须注册,获取个人认证码。

下载windows版本,并将下载的zip文件解压,将.exe文件复制到checkin-server文件夹当中。打开终端,切换到checkin-server目录,粘贴下载页面的这段代码,该代码为认证代码:

<token>部分为注册登陆后自动生成。复制粘贴到终端中运行完成之后,输入 ngrok http 3000开放端口渗透

bash 复制代码
ngrok http 3000

从运行结果中可以看到, https://36bc14c962e8.ngrok-free.app ,该链接极为访问到我们网页的链接。将该链接发送给其他人,其他人就可以访问到。

存在的问题:

  1. 由于ngrok是国外的工具,因此他自动选择最近的服务器是日本的,因此不挂梯子,可能进不去网页
  2. 每次重启ngrok之后,该链接都会变化。交钱注册会员,可以获得固定的二级域名,会员价格每个月三四块钱

因此,我们可以采用国内的内网穿透工具,有很多,这里只是拿NETAPP举例。

5,采用natapp工具进行内网穿透(国内工具)

打开网站 https://natapp.cn/ 。也是必须先注册,后使用

可以直接点击购买隧道,免费隧道,然后进行配置3000端口,获取自己的Authtoken,这相当于自己的登录密码

注册完成后,下载客户端,将natapp.exe文件放到checkin-server文件夹当中,打开终端,执行下列命令,激活自己的账号:

bash 复制代码
natapp -authtoken=你的authtoken字符串

然后输入natapp,即可成功运行该穿透工具。

bash 复制代码
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