所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

图片计数器总被刷新重复计数?手把手教你做防多次刷新的版本

图片计数器总被刷新重复计数?手把手教你做防多次刷新的版本 一

文章目录CloseOpen

我当时跟你一样头疼,翻了3篇技术文、问了2个程序员朋友,才搞懂问题出在哪儿,还把解决方法拆成了能跟着做的步骤。今天就把这些经验揉碎了讲,不用懂复杂代码也能搞定防刷新的图片计数器。

先搞懂:为什么刷新会重复计数?

要解决问题,得先明白“重复计数”的根子在哪儿。其实图片计数器的核心逻辑特别简单:每次加载图片文件,就会触发后端的计数接口。比如你把计数器做成一张图片(比如count.png),嵌在页面里,用户打开页面时,浏览器会自动请求这张图片,后端接到请求就给计数加1。

但刷新页面等于“重新加载所有资源”——包括这张count.png。所以哪怕是同一个用户,刷新一次页面,就会再请求一次图片,计数自然就多一次。我第一次做计数器的时候没考虑这点,结果朋友博客的“本周热门文章”里,一篇普通的“番茄鸡蛋做法”居然排第一,后来才发现是他自己刷新了20次测试导致的——你说这尴尬不尴尬?

更麻烦的是,有些用户会故意刷新刷流量(比如想让自己的评论排前面),或者用脚本自动刷新,这会让计数完全失真。所以要做“防刷新”的计数器,本质就是限制“同一用户在短时间内多次触发计数”

手把手做防刷新的图片计数器:分前端和后端两步

解决这个问题不用搞复杂框架,分“前端标记”和“后端验证”两步就行——我帮朋友做的时候,就用了这两个方法,现在他博客的计数数据准得很,连“今日访问量”都能用来判断哪些文章受欢迎。

第一步:前端用Cookie标记“是否已经计数”

前端的作用是“先拦一道”——用户第一次访问时,给浏览器留个“小标记”,下次再加载图片前先看这个标记,如果有,就不触发计数。

具体怎么做?用JavaScript写个简单的Cookie就行。比如:

  • 先写一段检查Cookie的代码:function hasVisited() { return document.cookie.indexOf('visited=1') !== -1; }——意思是“看看Cookie里有没有‘visited=1’这个标记”;
  • 然后在加载计数器图片前加个判断:如果hasVisited()返回false(没访问过),就加载图片并触发计数,同时设置Cookie:document.cookie = 'visited=1; max-age=86400;'max-age=86400是1天的秒数,意思是这个标记1天后失效);
  • 如果hasVisited()返回true(已经访问过),就用一张“空图片”代替计数器图片,或者直接不加载——这样刷新页面就不会重新计数了。
  • 我当时帮朋友做的时候,就用了这段代码,他试了下:第一次访问计数加1,刷新页面后计数没变化,连说“这才对嘛!”。不过要注意:Cookie可以被用户手动清除——比如有些用户会用“无痕模式”或者清除浏览器数据,这时候Cookie就失效了,还是会重复计数。所以得结合后端再拦一道。

    第二步:后端用Session/IP验证“是否允许计数”

    后端的作用是“再拦一道”——哪怕前端的Cookie被清除了,后端也能通过“用户专属标识”判断要不要计数。常用的方法有两个:Session验证和IP验证。

  • Session验证:用“用户专属ID”限制
  • Session是后端给每个用户分配的“专属编号”,比如用户第一次访问时,后端生成一个SessionID存在浏览器的Cookie里,下次访问时,后端通过这个SessionID就能认出“是同一个用户”。

    具体操作:

  • 后端接收计数请求时,先查这个用户的SessionID有没有在“已计数列表”里;
  • 如果没有,就给计数加1,同时把SessionID存到列表里,过期时间设为1小时(比如用Redis存,键是SessionID,值是1,过期时间3600秒);
  • 如果有,就直接拒绝这次计数请求。
  • 我当时用的是PHP+Redis,代码大概是这样的:

    session_start();
    

    $sessionId = session_id();

    if (!redis_exists($sessionId)) {

    // 计数加1

    incrementCount();

    // 存SessionID到Redis,1小时过期

    redis_set($sessionId, 1, 3600);

    }

    简单几行代码,就能防止同一用户1小时内重复计数。

  • IP验证:用“设备地址”限制
  • 如果你的站点不用登录(比如公开的博客、文档站),没法用Session,那就用IP地址验证——同一IP地址在短时间内只能计数一次。

    具体操作:

  • 后端接收计数请求时,先获取用户的IP地址(比如PHP里的$_SERVER['REMOTE_ADDR']);
  • 查这个IP有没有在“已计数IP列表”里,如果没有,就计数并把IP存到列表,过期时间设为1小时;
  • 如果有,就拒绝请求。
  • 这里要注意:有些用户用的是“共享IP”(比如公司局域网、网吧),这时候会误判——比如同一公司的10个用户用同一个IP,只会计数1次。所以我 你把IP验证和Cookie结合用,比如:如果Cookie存在,就不计数;如果Cookie不存在,再查IP——这样能减少误判。

    附:不同验证方式的优缺点对比

    我整理了一张表,帮你选适合自己站点的方式:

    验证方式 优点 缺点 适用场景
    Cookie 代码简单,不用后端存储 用户可清除,易失效 个人博客、小型静态站点
    Session 用户专属,不易伪造 需要后端存储Session 需要登录的站点(如社区、电商)
    IP 限制同一设备,无需用户操作 共享IP会误判 公开无登录的站点(如文档站、资讯站)

    最后说几个“避坑”小技巧

    我帮朋友做的时候踩过几个坑,提前告诉你省得走弯路:

  • Cookie过期时间别设太短:比如设成10分钟,用户中途刷新还是会计数——我之前试过设30分钟,结果朋友说“刷新两次还是加了数”,后来改成1天就好了;
  • 后端要加缓存:比如用Redis存已计数的Session或IP,别直接查数据库——我一开始用MySQL存,查询一次要0.5秒,后来换成Redis,速度降到0.01秒,站点加载快了很多;
  • 测试的时候多换设备:比如用手机、电脑、平板都试一遍,确保不同设备的计数不会重复——我当时用自己的手机试,第一次访问计数加1,刷新没变化,用电脑访问又加1,这才说明有效。
  • 你跟着做的时候,如果遇到“Cookie设置不成功”或者“后端验证没生效”的问题,随时留言告诉我——我帮你看看代码哪里错了。或者做完后,用不同设备刷新几次,看看计数是不是只加一次——如果成了,记得回来跟我报个喜!


    本文常见问题(FAQ)

    为什么刷新页面会让图片计数器重复计数?

    图片计数器的核心逻辑是每次加载图片文件都会触发后端计数接口,比如你把计数器做成count.png嵌在页面里,用户打开页面时浏览器会请求这张图片,后端接到请求就加1。

    但刷新页面等于重新加载所有资源,包括这张count.png,所以同一个用户刷新一次页面,就会再请求一次图片,计数自然多一次,我之前帮朋友做计数器时没考虑这点,结果他自己刷新20次测试,导致一篇普通文章的计数虚高排到热门第一。

    前端用Cookie防刷新计数的原理是什么?

    前端的作用是先拦一道,用户第一次访问时给浏览器留个“小标记”,比如用JavaScript写段检查Cookie的代码,看看有没有“visited=1”这个标记,如果没有就加载图片触发计数,同时设置Cookie标记;如果有,就不加载图片,这样刷新页面就不会重复触发计数了。

    不过Cookie能被用户手动清除,比如用无痕模式或清浏览器数据,所以得结合后端再拦一道才保险。

    后端用Session和IP验证防刷新的区别是什么?

    Session是后端给每个用户分配的专属ID,存在浏览器Cookie里,用户第一次访问时后端生成SessionID,下次访问通过这个ID认出同一用户,没在已计数列表里就加1,还能存在Redis里设1小时过期,优点是用户专属不易伪造,但需要后端存储Session。

    IP验证是获取用户的设备地址,比如PHP里的$_SERVER[‘REMOTE_ADDR’],同一IP短时间内只能计数一次,优点是不用用户操作,但有些用户用共享IP(比如公司局域网、网吧),会导致同一IP下多个真实用户只计数一次,容易误判。

    Cookie过期时间设多久合适?

    别设太短,比如我之前试过设30分钟,结果朋友说刷新两次还是加了数,后来改成1天(86400秒)就好了,这样用户当天内刷新页面不会重复计数,既保证数据准确,也不会影响第二天的新访问计数。

    如果设得太短,比如10分钟,用户中途刷新页面还是会触发计数,设太长又可能影响真实新访问的计数,1天是比较平衡的选择。

    前端Cookie被清除了怎么办?

    单靠前端Cookie确实有失效的风险,比如用户清了浏览器数据或用无痕模式,这时候就得结合后端验证,比如用Session或IP验证,双重保险。

    比如前端Cookie被清了,后端会查SessionID或IP,如果这两个也没记录,才会触发计数,这样就算Cookie失效,也能避免同一用户短时间内重复计数,我帮朋友做的时候就是这么组合用的,现在他博客的计数数据准得很。

    原文链接:https://www.mayiym.com/52799.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码