You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NodeJS后端结合JS连接HTML时页面持续刷新,浏览量异常增长

页面统计功能异常:页面持续刷新导致计数疯涨

问题描述

开发网站访客数与页面浏览量统计功能时,启动后端服务器后页面出现持续自动刷新,页面浏览量计数不断异常增长,同时访客数也存在重复统计的问题。

相关代码

HTML代码

<h2>Page Views: <span id="pageviews-count"></span></h2>
<h2>Visits: <span id="visits-count"></span></h2>

页面脚本

const pageviewsCount = document.getElementById('pageviews-count');
const visitsCounts = document.getElementById('visits-count');

if (sessionStorage.getItem('visit') === null) {
    updateCounter('type=visit-pageview');
}
else {
    updateCounter('type=pageview');
}

function updateCounter(type) {
    fetch('http://localhost:5000/counter?' + type)
        .then(res => res.json())
        .then(data => {
            pageviewsCount.textContent = data.pageviews;
            visitsCounts.textContent = data.visits;
        })
}

计数器控制器(counter.controller.js)

const fs = require('fs');

async function visitCounter(req, res, next) {
    if (req.url === '/favicon.ico') {
        res.end();
    }

    const json = fs.readFileSync('./logs/count.json', 'utf-8');
    const obj = JSON.parse(json);

    obj.pageviews = obj.pageviews + 1;

    if (req.query.type === 'visit-pageview') {
        obj.visits = obj.visits + 1;
    }

    const newJson = JSON.stringify(obj);
    fs.writeFileSync('./logs/count.json', newJson);

    res.send(newJson);

}

module.exports = visitCounter

计数器路由(counter.routes.js)

const express = require('express');
const counter = require('../controllers/counter.controller');

const router = express.Router();

router.route('/')
    .get(counter);

module.exports = router;

计数存储文件(count.json)

{"pageviews":369,"visits":8}

主应用文件(app.js)

const express = require("express");
const cors = require("cors");

const app = express();
const port = 5000;

app.use(express.json());
app.use(cors());
app.use('/counter', require('./routes/counter.routes'));
app.listen(port, () => {
    console.log(`http://localhost:${port}`);
});

问题分析与修复

核心问题

  1. 后端未终止/favicon.ico请求:浏览器每次加载页面都会请求/favicon.ico,后端代码中执行res.end()后没有return,后续计数逻辑仍会运行,导致该请求也会增加浏览量;同时返回的JSON不是浏览器预期的图标资源,引发页面异常刷新。
  2. 前端未设置会话标记:第一次访问时触发访客计数,但未在sessionStorage中标记会话状态,导致页面刷新后重复触发访客数增长。

修复代码

1. 修正后端控制器

const fs = require('fs');

async function visitCounter(req, res, next) {
    if (req.url === '/favicon.ico') {
        res.status(204).end(); // 返回204无内容,告知浏览器无需重试请求
        return; // 终止后续代码,避免计数逻辑执行
    }

    const json = fs.readFileSync('./logs/count.json', 'utf-8');
    const obj = JSON.parse(json);

    obj.pageviews = obj.pageviews + 1;

    if (req.query.type === 'visit-pageview') {
        obj.visits = obj.visits + 1;
    }

    const newJson = JSON.stringify(obj);
    fs.writeFileSync('./logs/count.json', newJson);

    res.send(newJson);
}

module.exports = visitCounter

2. 修正前端脚本

const pageviewsCount = document.getElementById('pageviews-count');
const visitsCounts = document.getElementById('visits-count');

if (sessionStorage.getItem('visit') === null) {
    updateCounter('type=visit-pageview');
    sessionStorage.setItem('visit', '1'); // 标记会话,同一会话内不再重复统计访客
} else {
    updateCounter('type=pageview');
}

function updateCounter(type) {
    fetch('http://localhost:5000/counter?' + type)
        .then(res => res.json())
        .then(data => {
            pageviewsCount.textContent = data.pageviews;
            visitsCounts.textContent = data.visits;
        })
}

额外优化建议

  • 后端改用异步文件读写(fs.promises.readFile/fs.promises.writeFile),避免同步操作阻塞服务器;
  • 准备实际的favicon.ico文件,或为该请求返回正确的图标类型响应;
  • 高并发场景下,建议用数据库(如Redis、SQLite)替代JSON文件存储计数,防止并发写入导致数据丢失。

内容的提问来源于stack exchange,提问作者Resai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 15:58:10