怎样实现浏览数据统计脚本

wen 实用脚本 26

本文目录导读:

怎样实现浏览数据统计脚本

  1. 基础页面访问统计(纯前端)
  2. 使用第三方服务(百度统计)
  3. 完整的Node.js + MongoDB后端方案
  4. 发送统计数据到服务器
  5. 使用建议

我来帮你实现一个完整的浏览数据统计脚本,这里提供几种不同场景的实现方案:

基础页面访问统计(纯前端)

// page-view-stats.js
class PageViewTracker {
  constructor(options = {}) {
    this.options = {
      storageKey: 'page_views',      // localStorage键名
      trackHistory: true,            // 是否记录历史浏览
      ...options
    };
    this.init();
  }
  init() {
    // 增加页面访问次数
    this.incrementPageView();
    // 记录浏览历史
    if (this.options.trackHistory) {
      this.recordHistory();
    }
    // 监听页面关闭/切换
    this.listenVisibilityChange();
  }
  // 获取当前页面访问次数
  getPageViews() {
    const pageKey = this.getPageKey();
    const data = JSON.parse(localStorage.getItem(this.options.storageKey) || '{}');
    return data[pageKey] || 0;
  }
  // 增加页面访问次数
  incrementPageView() {
    const pageKey = this.getPageKey();
    const data = JSON.parse(localStorage.getItem(this.options.storageKey) || '{}');
    data[pageKey] = (data[pageKey] || 0) + 1;
    localStorage.setItem(this.options.storageKey, JSON.stringify(data));
    // 触发自定义事件
    this.emitEvent('pageView', {
      page: pageKey,
      count: data[pageKey],
      timestamp: Date.now()
    });
  }
  // 获取页面标识
  getPageKey() {
    return window.location.pathname + window.location.search;
  }
  // 记录浏览历史
  recordHistory() {
    const historyKey = 'page_history';
    const history = JSON.parse(localStorage.getItem(historyKey) || '[]');
    history.push({
      page: this.getPageKey(),
      title: document.title,
      time: new Date().toISOString(),
      referrer: document.referrer
    });
    // 只保留最近1000条记录
    if (history.length > 1000) {
      history.shift();
    }
    localStorage.setItem(historyKey, JSON.stringify(history));
  }
  // 监听页面可见性变化
  listenVisibilityChange() {
    document.addEventListener('visibilitychange', () => {
      if (document.hidden) {
        this.emitEvent('pageHidden');
      } else {
        this.emitEvent('pageVisible');
      }
    });
  }
  // 触发自定义事件
  emitEvent(name, data = {}) {
    const event = new CustomEvent(name, { detail: data });
    document.dispatchEvent(event);
  }
  // 获取统计数据
  getStats() {
    const data = JSON.parse(localStorage.getItem(this.options.storageKey) || '{}');
    const history = JSON.parse(localStorage.getItem('page_history') || '[]');
    return {
      totalViews: Object.values(data).reduce((a, b) => a + b, 0),
      pageViews: data,
      recentHistory: history.slice(-10)  // 最近10条记录
    };
  }
}

使用第三方服务(百度统计)

<!-- 在HTML中引入 -->
<script>
var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?你的跟踪ID";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();
// 自定义事件跟踪
function trackEvent(category, action, label, value) {
  _hmt.push(['_trackEvent', category, action, label, value]);
}
</script>

完整的Node.js + MongoDB后端方案

// server.js - 后端统计服务
const express = require('express');
const mongoose = require('mongoose');
const app = express();
// MongoDB模型
const PageViewSchema = new mongoose.Schema({
  page: String,
  ip: String,
  userAgent: String,
  referrer: String,
  timestamp: { type: Date, default: Date.now },
  sessionId: String
});
const PageView = mongoose.model('PageView', PageViewSchema);
// 统计中间件
app.use(async (req, res, next) => {
  // 排除静态资源和某些路径
  const excludePaths = ['/favicon.ico', '/robots.txt', '/api/'];
  if (excludePaths.some(path => req.path.startsWith(path))) {
    return next();
  }
  try {
    await PageView.create({
      page: req.path,
      ip: req.ip,
      userAgent: req.headers['user-agent'],
      referrer: req.headers['referer'] || '',
      sessionId: req.sessionID
    });
  } catch (error) {
    console.error('统计记录失败:', error);
  }
  next();
});
// API接口
app.get('/api/stats', async (req, res) => {
  try {
    const stats = await PageView.aggregate([
      {
        $group: {
          _id: '$page',
          count: { $sum: 1 },
          lastVisit: { $max: '$timestamp' }
        }
      },
      { $sort: { count: -1 } }
    ]);
    res.json({
      total: await PageView.countDocuments(),
      pages: stats
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});
app.listen(3000, () => {
  console.log('统计服务运行在 http://localhost:3000');
});

发送统计数据到服务器

// analytics.js - 前端发送统计
class Analytics {
  constructor(endpoint) {
    this.endpoint = endpoint;
    this.sessionId = this.generateSessionId();
    // 页面加载完成时发送数据
    window.addEventListener('load', () => this.sendPageView());
    // 页面退出前发送数据
    window.addEventListener('beforeunload', () => this.sendBeacon());
  }
  // 生成会话ID
  generateSessionId() {
    let sessionId = sessionStorage.getItem('session_id');
    if (!sessionId) {
      sessionId = 'sess_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
      sessionStorage.setItem('session_id', sessionId);
    }
    return sessionId;
  }
  // 发送页面浏览
  sendPageView() {
    const data = {
      type: 'pageview',
      sessionId: this.sessionId,
      page: window.location.pathname,
      title: document.title,
      referrer: document.referrer,
      screenWidth: screen.width,
      screenHeight: screen.height,
      language: navigator.language,
      timestamp: Date.now()
    };
    this.sendData('/api/track', data);
  }
  // 使用Beacon API发送
  sendBeacon() {
    const data = {
      type: 'pageleave',
      sessionId: this.sessionId,
      timeSpent: Date.now() - performance.timing.navigationStart
    };
    navigator.sendBeacon(this.endpoint + '/api/beacon', JSON.stringify(data));
  }
  // 发送数据
  async sendData(path, data) {
    try {
      const response = await fetch(this.endpoint + path, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
      });
      if (!response.ok) {
        console.error('统计发送失败:', response.status);
      }
    } catch (error) {
      console.error('统计发送错误:', error);
    }
  }
  // 自定义事件跟踪
  trackEvent(eventName, properties = {}) {
    this.sendData('/api/event', {
      type: 'event',
      sessionId: this.sessionId,
      event: eventName,
      properties,
      timestamp: Date.now()
    });
  }
}
// 使用示例
const analytics = new Analytics('https://your-server.com');
// 点击按钮时跟踪
document.getElementById('buy-now').addEventListener('click', () => {
  analytics.trackEvent('click_buy_now', { price: 99.9 });
});

使用建议

选择适合的方案:

  • 简单页面统计:使用localStorage的前端方案
  • 专业网站统计:百度统计、Google Analytics
  • 自建统计系统:后端方案 + 前端发送

最佳实践:

  1. 数据隐私:遵守相关法规,告知用户
  2. 压缩数据:批量发送减少请求
  3. 降级方案:确保统计失败不影响页面功能
  4. 去重处理:避免重复统计(防刷)

需要我详细解释某个部分或提供特定场景的优化吗?

抱歉,评论功能暂时关闭!