如何使用 js 统计访问量及网站运行时间

我打算用思源的 Docker 发布功能搭建博客,但不知如何统计访问量。能否提供一段 JS 代码,实现记录访问量和网站运行时间,并将这些信息显示在侧边栏?另外,希望代码存储的数据能通过 S3 同步或打包。

  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    25755 引用 • 106601 回帖
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    9871 引用 • 44874 回帖 • 78 关注

相关帖子

被采纳的回答
  • wilsons 1 1 赞同

    写了一个代码,但不知你说的侧边栏是指放哪?感觉放不下,所以放状态栏了。

    另外,手机版也不知道哪里有位置显示,所以暂不支持。

    仅供参考。

    image.png

    // 统计网站访问量和运行时间 (async ()=>{ // api地址,最后不要加 / const apiUrl = 'http://127.0.0.1:6806'; // api token 在设置->关于中查看 const apiToken = ''; // 初始化数据 const initData = { // 网站总访问量 total: 0, // 网站运行初始日期 startDay: '2025-04-13' }; // 定义统计信息显示模板 const tongjiTpl = `总访问量:{total}&nbsp;&nbsp;网站运行:{runningDays}天`; // 已统计的跳过 if(document.querySelector('#status .site__tongji')) return; // 记录初始访问量 const initTotal = initData.total || 0; // 延迟等待数据加载和同步 await sleep(1500); // 获取置顶数据,格式 {"total":0, "startDay":''} let data = await getFile('/data/storage/site_tongji.json'); data = JSON.parse(data||'{}'); if(data.code && data.code !== 0) data = {}; data = {...initData, ...data}; // 仅网站版和发布服务版才统计 if(siyuan.config.readonly && isBrowser()) { // 当不存在total字段时初始化 if(!data.total) data.total = 0; // 当总数小于初始化值时,直接赋值为初始化的值 if(data.total < initTotal) data.total = initTotal; // 网站访问+1 data.total++; // 存储网站访问数据 if(data.total > 0) putFile('/data/storage/site_tongji.json', JSON.stringify(data, null, 4)); } // 获取网站运行时间 const runningDays = calculateRunningDays(data); // 状态栏显示统计信息 showStatusMsg(tongjiTpl.replace('{total}', data.total).replace('{runningDays}', runningDays)); // 计算网站运行时间(单位:天) function calculateRunningDays(data) { // 获取当前日期并重置时间为 00:00:00 const currentDate = new Date(); resetTime(currentDate); // 解析初始日期并重置时间为 00:00:00 const startDate = new Date(data.startDay); if (isNaN(startDate.getTime())) { return 1; } resetTime(startDate); // 计算时间差(毫秒) const timeDifference = currentDate - startDate; // 转换为天数 const daysDifference = Math.floor(timeDifference / (1000 * 60 * 60 * 24)); return daysDifference + 1; } function resetTime(date) { date.setHours(0, 0, 0, 0); // 设置时间为 00:00:00.000 return date; } // 状态栏输出 function showStatusMsg(html) { const statusMsg = document.querySelector('#status .status__msg'); if(!statusMsg) return; const tongji = document.querySelector('#status .site__tongji'); if(tongji) tongji.remove(); const style = ` color: var(--b3-theme-on-surface); white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding-left: 5px; font-size: 12px; `; html = `<div class="site__tongji" style="${style}">${html}</div>`; statusMsg.insertAdjacentHTML('beforebegin', html); } function isBrowser() { return !navigator.userAgent.startsWith("SiYuan") || navigator.userAgent.indexOf("iPad") > -1 || (/Android/.test(navigator.userAgent) && !/(?:Mobile)/.test(navigator.userAgent)); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } // 获取文件 async function getFile(path) { return fetch("/api/file/getFile", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ path, }), }).then((response) => { if (response.ok) { return response.text(); } else { throw new Error("Failed to get file content"); } }).catch((error) => { console.error(error); }); } // 存储文件,支持创建文件夹,当isDir true时创建文件夹,忽略文件 async function putFile(path, content = '', isDir = false) { const formData = new FormData(); formData.append("path", path); formData.append("isDir", isDir) formData.append("file", new Blob([content])); const result = await fetch(apiUrl+"/api/file/putFile", { // 写入js到本地 method: "POST", headers: { "Authorization": "token " + apiToken // 添加 Authorization 头 }, body: formData, }); const json = await result.json(); return json; } })();

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 51LA 统计可以,并支持显示简单统计面板,由于第三方统计,都免去打包的麻烦了。

  • 其他回帖
  • CongSec

    可以一直显示吗?刚开始访问的时候就可以显示出来,但是过了一分钟左右就消失了

    image.png

    1 回复
  • siyuan100861186 1 1 赞同

    有一个嵌入式的程序,umami,这个直接嵌入网站就可以统计访问信息了

  • CongSec 3 评论

    今天起床发现,服务端访问量从 168 回归到 5,期间的过程我想是因为归零一次了,以下是服务端的日志:

    systemlog.zip

    还麻烦你增强下代码的健壮性,把归零的代码逻辑部分去掉;

    image.png

    你最近有做什么吗?先推测下可能的原因,这样才能针对的解决问题。大致方向是同步的锅,比如存储的统计数据,尚未同步成功时被执行了存储操作,还有如果客户端上开启了只读模式,如果尚未同步成功,可能会被重写数据。所以,现在做了以下几种限制:1 仅发布服务和浏览器访问才统计,2 网站加载时暂停 1.5 秒执行,等待数据同步完成 3 判断已存数据是否小于初始数据 4 数据只有大于 0 的时候才被存储
    wilsons 1
    @wilsons 我的使用场景主要如下:服务器挂载 docker 启动发布功能充当博客,另一边是我的本机电脑, 两者的数据同步方式是采用 s3 同步,我的本机电脑更改数据点击同步会自动同步到服务器的 docker 当中,刚开始的几天内可以正常使用,也就是今天起床时候出现了故障,我启动博客(服务端的发布功能)查看,发现那里的访问量是 5 个,而我的本机电脑的访问量为 168,是正常的,没过多久,我本机的访问量也变成了 5 了,因该是服务器同步下来的,具体原因尚未清楚
    CongSec
    @CongSec 这种场景其实是有问题的,首先你得保证 docker 和电脑都 30 秒同步一次,即使这样中间也会有 10 分钟左右的误差,可能造成 10 分钟内的数据被覆盖,建议用我的同步感知 js 代码,可以把这个时间缩短至 30 秒。但这都不是最佳方案,建议最佳方式在 docker 的思源空间 data 目录外添加个标志文件,比如 docker.lock,然后我在 js 里判断是否存在这个文件,只在存在这个文件时才写统计数据,只要不存在都仅只读。当然这个 docker.lock 也可以放到 data 内,然后用忽略文件忽略,不过这样较麻烦,不推荐。
    wilsons
  • 查看全部回帖
CongSec
新手可以看我发的求助帖以及汇总帖子,很有帮助的!_! 网安笔记分享:http://congsec.xyz 北京

推荐标签 标签

  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 676 关注
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 834 关注
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    77 引用 • 37 回帖 • 1 关注
  • 导航

    各种网址链接、内容导航。

    44 引用 • 177 回帖
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    54 引用 • 37 回帖 • 1 关注
  • 职场

    找到自己的位置,萌新烦恼少。

    127 引用 • 1708 回帖
  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    10 引用 • 77 回帖
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖 • 1 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    17 引用 • 53 回帖 • 145 关注
  • OpenShift

    红帽提供的 PaaS 云,支持多种编程语言,为开发人员提供了更为灵活的框架、存储选择。

    14 引用 • 20 回帖 • 662 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    89 引用 • 1251 回帖 • 398 关注
  • Ubuntu

    Ubuntu(友帮拓、优般图、乌班图)是一个以桌面应用为主的 Linux 操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu 的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。

    127 引用 • 169 回帖
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 487 关注
  • 服务器

    服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。

    125 引用 • 585 回帖
  • Markdown

    Markdown 是一种轻量级标记语言,用户可使用纯文本编辑器来排版文档,最终通过 Markdown 引擎将文档转换为所需格式(比如 HTML、PDF 等)。

    171 引用 • 1537 回帖
  • Follow
    4 引用 • 12 回帖 • 3 关注
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 654 关注
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖
  • 生活

    生活是指人类生存过程中的各项活动的总和,范畴较广,一般指为幸福的意义而存在。生活实际上是对人生的一种诠释。生活包括人类在社会中与自己息息相关的日常活动和心理影射。

    229 引用 • 1432 回帖
  • 禅道

    禅道是一款国产的开源项目管理软件,她的核心管理思想基于敏捷方法 scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。

    8 引用 • 15 回帖 • 6 关注
  • sts
    2 引用 • 2 回帖 • 236 关注
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 284 关注
  • FreeMarker

    FreeMarker 是一款好用且功能强大的 Java 模版引擎。

    23 引用 • 20 回帖 • 464 关注
  • Vim

    Vim 是类 UNIX 系统文本编辑器 Vi 的加强版本,加入了更多特性来帮助编辑源代码。Vim 的部分增强功能包括文件比较(vimdiff)、语法高亮、全面的帮助系统、本地脚本(Vimscript)和便于选择的可视化模式。

    29 引用 • 66 回帖
  • HHKB

    HHKB 是富士通的 Happy Hacking 系列电容键盘。电容键盘即无接点静电电容式键盘(Capacitive Keyboard)。

    5 引用 • 74 回帖 • 515 关注
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    91 引用 • 59 回帖 • 4 关注