因为如果只存在浏览器中(比如使用 localStorage),每个用户访问时看到的都只是自己的访问计数,而不是网站的总访问量。

(图片来源网络,侵删)
下面我将为您详细解释实现原理,并提供从简单到专业的多种代码方案。
核心原理
- 前端:用户访问你的网页时,浏览器会加载一个包含 HTML、CSS、JavaScript 的页面。
- JavaScript:页面加载后,一个 JavaScript 函数会被触发。
- API 请求:这个 JS 函数会向后端服务器发送一个请求,“嘿,服务器,有人访问了我的网站,请帮我更新一下访问计数。”
- 后端处理:
- 服务器收到请求后,会连接到数据库。
- 在数据库中,找到存储访问次数的那个记录(比如一个名为
visitors的表,里面有一个count字段)。 - 将
count的值加 1。 - 将新的
count值保存回数据库。 - 将新的
count值作为响应返回给前端。
- 前端显示:前端的 JavaScript 接收到服务器返回的新计数值,并将其动态地显示在网页的指定位置。
关键组件:
- 前端: HTML + JavaScript
- 后端: 服务器(可以是 Node.js, Python, PHP, Java 等)
- 数据库: 用于持久化存储访问次数(可以是 Redis, MySQL, MongoDB 等)
使用第三方统计服务(最简单、最推荐)
对于绝大多数个人博客或小型网站,不需要自己搭建后端,直接使用成熟的第三方服务是最佳选择,它们不仅提供访问次数,还提供更丰富的用户行为分析。
推荐服务:

(图片来源网络,侵删)
- Google Analytics (谷歌分析):行业标准,功能强大,完全免费。
- Clarity (微软 Clarity):免费,提供会话录制和热力图,非常直观。
- 不蒜子 (busuanzi.ibruce.info):一个轻量、免费、无需注册的极简计数器服务,非常适合只想显示访问次数的场景。
示例:使用“不蒜子”服务
这是最简单的纯 HTML/CSS/JS 方案,你甚至不需要自己的服务器。
- 在你的 HTML 文件中,在你想显示访问次数的地方(例如页脚)添加以下代码:
<!-- 显示本站总访问量 PV -->
<span id="busuanzi_container_site_pv">
本站总访问量 <span id="busuanzi_value_site_pv"></span> 次
</span>
<!-- 显示本站总访客数 UV -->
<span id="busuanzi_container_site_uv">
本站总访客数 <span id="busuanzi_value_site_uv"></span> 人
</span>
- 在 HTML 的
<head>或<body>底部,添加不蒜子的 JavaScript 脚本:
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
就这么简单! 当你的页面加载时,这个脚本会自动请求不蒜子的服务器,获取并显示你网站的 PV (Page View, 页面浏览量) 和 UV (Unique Visitor, 独立访客数)。
使用 Firebase(无服务器方案,非常灵活)
如果你不想写后端代码,但希望数据存储在自己的账户中,Firebase 是一个绝佳的选择,它提供了免费的额度,足够小型项目使用。

(图片来源网络,侵删)
步骤:
-
创建 Firebase 项目:
- 访问 Firebase 控制台,用 Google 账号登录。
- 创建一个新项目。
- 在项目中,启用 "Firestore Database"(云数据库),选择 "测试模式" 以便快速开发。
- 创建一个集合 (Collection),比如命名为
counters,并在其中创建一个文档 (Document),命名为visits,在这个文档里添加一个字段,count,初始值设为0。
-
配置网页:
- 在 Firebase 控制台的 "项目设置" -> "常规" 页面,找到你的 Web App SDK 配置,复制它。
- 在你的 HTML 文件中,引入 Firebase SDK 和你的配置信息。
-
编写 HTML 和 JavaScript 代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">访问次数统计</title>
<!-- 1. 引入 Firebase 核心库和 App 库 -->
<script src="https://www.gstatic.com/firebasejs/9.15.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/9.15.0/firebase-firestore-compat.js"></script>
<!-- 2. 在这里粘贴你的 Firebase 配置 -->
<script>
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_STORAGE_BUCKET",
messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
appId: "YOUR_APP_ID"
};
// 初始化 Firebase
firebase.initializeApp(firebaseConfig);
const db = firebase.firestore();
</script>
</head>
<body>
<h1>欢迎访问我的网站</h1>
<p>总访问次数: <strong id="visit-count">加载中...</strong></p>
<script>
// 获取显示计数的元素
const visitCountElement = document.getElementById('visit-count');
// 获取 Firestore 数据库的引用
const visitsRef = db.collection('counters').doc('visits');
// 使用事务 (Transaction) 来确保计数的原子性
// 防止在高并发时计数出错
db.runTransaction(transaction => {
return transaction.get(visitsRef).then(doc => {
// 如果文档不存在,则创建它,初始值为 1
// 如果文档存在,则获取当前值并加 1
const newCount = (doc.data() ? doc.data().count : 0) + 1;
transaction.update(visitsRef, { count: newCount });
return newCount;
});
}).then(newCount => {
// 更新页面上的显示
visitCountElement.textContent = newCount;
}).catch(error => {
console.error("Error updating visit count: ", error);
visitCountElement.textContent = "无法加载";
});
</script>
</body>
</html>
传统后端 + 数据库方案(最专业、最可控)
如果你有自己的服务器,或者想学习完整的全栈开发,这是最标准的做法,这里以 Node.js + Express + MongoDB 为例。
后端代码 (Node.js)
你需要一个 package.json 文件,并安装 express 和 mongodb。
npm init -y npm install express mongodb
创建一个 server.js 文件:
// server.js
const express = require('express');
const { MongoClient, ServerApiVersion } = require('mongodb');
const app = express();
const port = 3000;
// --- MongoDB 配置 ---
const uri = "mongodb://localhost:27017"; // 你的 MongoDB 连接字符串
const client = new MongoClient(uri, {
serverApi: {
version: ServerApiVersion.v1,
strict: true,
deprecationErrors: true,
}
});
let visitsCollection;
// 连接到 MongoDB
async function run() {
try {
await client.connect();
console.log("成功连接到 MongoDB!");
// 访问数据库和集合
const database = client.db("myWebsiteDB");
visitsCollection = database.collection("visits");
// 确保计数文档存在
await visitsCollection.updateOne(
{ _id: "total_visits" }, // 查询条件
{ $setOnInsert: { count: 0 } }, // 如果不存在则插入
{ upsert: true } // 如果文档不存在则插入
);
} catch (err) {
console.error(err);
}
}
run().catch(console.dir);
// --- API 路由 ---
// 端点:增加访问次数
app.post('/api/increment-visits', async (req, res) => {
try {
const result = await visitsCollection.updateOne(
{ _id: "total_visits" },
{ $inc: { count: 1 } } // 使用 $inc 原子操作将 count 字段加 1
);
// 获取更新后的最新计数
const doc = await visitsCollection.findOne({ _id: "total_visits" });
res.status(200).json({ count: doc.count });
} catch (error) {
res.status(500).json({ error: "增加访问次数失败" });
}
});
// 端点:获取访问次数
app.get('/api/get-visits', async (req, res) => {
try {
const doc = await visitsCollection.findOne({ _id: "total_visits" });
if (doc) {
res.status(200).json({ count: doc.count });
} else {
res.status(404).json({ error: "未找到访问次数记录" });
}
} catch (error) {
res.status(500).json({ error: "获取访问次数失败" });
}
});
app.listen(port, () => {
console.log(`服务器正在 http://localhost:${port} 上运行`);
});
前端代码 (HTML + JavaScript)
创建一个 index.html 文件,它将从后端 API 获取数据。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">访问次数统计</title>
</head>
<body>
<h1>欢迎访问我的网站</h1>
<p>总访问次数: <strong id="visit-count">加载中...</strong></p>
<script>
const visitCountElement = document.getElementById('visit-count');
const API_URL = 'http://localhost:3000/api/get-visits';
// 页面加载时获取访问次数
window.addEventListener('DOMContentLoaded', () => {
fetchVisits();
});
// 页面关闭或刷新时,向服务器发送请求增加访问次数
// 注意:这个方法不是 100% 可靠的,但作为演示足够了
window.addEventListener('beforeunload', () => {
incrementVisits();
});
async function fetchVisits() {
try {
const response = await fetch(API_URL);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
visitCountElement.textContent = data.count;
} catch (error) {
console.error("无法获取访问次数:", error);
visitCountElement.textContent = "无法加载";
}
}
async function incrementVisits() {
try {
await fetch(API_URL, { method: 'POST' });
} catch (error) {
console.error("无法增加访问次数:", error);
}
}
</script>
</body>
</html>
如何运行:
- 确保你的电脑上安装并运行了 MongoDB。
- 运行
node server.js启动后端服务器。 - 在浏览器中打开
index.html文件。
总结与选择建议
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 第三方服务 | 最简单,无需后端,功能强大,免费 | 数据在第三方,有隐私顾虑,依赖服务可用性 | 绝大多数个人博客、企业官网、小型项目。首选方案。 |
| Firebase | 无需自己管理服务器,免费额度足够,数据在自己账户 | 学习成本略高,长期大量数据可能产生费用 | 中小型项目,希望有数据自主权,不想写后端代码的开发者。 |
| 传统后端+数据库 | 最专业,完全自主可控,性能高,可扩展性强 | 需要自己搭建和维护服务器,开发周期长,成本高 | 大型网站、对数据安全和性能有极高要求的专业项目。 |
对于初学者或快速实现需求,强烈推荐方案一(不蒜子),如果你想深入学习全栈开发,方案三(Node.js + MongoDB) 是一个很好的实践项目。
