×

Loading...

@Ottawa

Topic

This topic has been archived. It cannot be replied.
  • 工作学习 / 学科技术 / 看到很多人还在用政治讨论【环球日报发起释放孟晚舟的联署,被发现作弊】。作为IT资深人士,我几乎一口咖啡喷在屏幕上,只欢迎IT技术人士共同切磋,我虽然已经研究透了这个投票逻辑,基于高尚的品格,只投了一次哈 +8

    整个网页,每隔60秒用ajax call 从后台获取实际的签名数字,自己用这个url试https://vote.huanqiu.com/api/v1/num。

    它那个动画数字只是为了吸引眼球用的,一段时间就会用ajax call从后台更新实际的数据,

    网站更新数据和submit 签名都是asynchronous,它提到是fingerprint防止多次签名,但是实际上非常容易就可以实现多次签名,但是网站的block IP技术还是有些水平的,总之,从网站的设计上看并不能发现作弊,当然后台的数据,就没人知道了


    :


    // var fgId = '7okx3d4yk2';
    // var is_sign = 'is_sign_' + fgId;
    // var language1 = 'language_' + fgId;

    var u = navigator.userAgent;
    var iswindows = (u.indexOf("Windows",0) != -1)?1:0;  
    var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; 
    if(iswindows || isAndroid){
      // $('#clock .time-container .num').css('line-height', '1.2266666666666666rem');
    }
    // 中英文
    renders(language);
    function renders(t){
      document.title = languageText[t].headTile;
      $('.numberOf').text(languageText[t].signNum);
      $('.titSmall').html(languageText[t].titSmall);
      $('.slide1 h5').html(languageText[t].tit1);
      $('.slide1 .conts p').html(languageText[t].content1);
      $('.slide2 h5').html(languageText[t].tit2);
      $('.slide2 .conts p').html(languageText[t].content2);
      $('.conts span.packUp').text(languageText[t].packUp);
      $('.foot p').text(languageText[t].footText);
      $('.language').text(languageText[t].btnText);
      
      $('.switch').css('opacity',1);
      $('body,html').animate({ scrollTop: 0 }, 100);;
      isSlide = false;
      messageOut1();
      // 需要重新获取投票数
      getInfo();
      // 初始每分钟获取数据
      perMinutes();
      // 初始化按钮
      // initSignBtn();
    }

    var isClick;
    // 验证本地存的local是否有效
    initFingerprintJS(verifyRequest);
    var visitorId = '80017177de1cb67cf66ae6c5f1e00008';
    function initFingerprintJS(verifyRequest) {
      var fpPromise = FingerprintJS.load(); 
      fpPromise.then(function (fp) {
        return fp.get();
      }).then(function (result) {
        visitorId = result.visitorId;
        // console.log(visitorId);
        verifyRequest(visitorId);
      });
    }
    function verifyRequest(fingerprint){
      if(localStorage.getItem(is_sign) === 'true' ){
        $('.zhuan').removeClass('zhuanIng').addClass('zhuanEnd');
        $('.btnSig').addClass('btnSigEnd');
        isClick = true;
        return false;
      }
      $.ajax({
        url: '/api/v1/verify',
        type: 'POST',
        data: {"id":fgId,"fingerprint":fingerprint}
      })
      .done(function(res) {
        // 已经签名
        if(res.code !== 0){
          // $('.sign').removeAttr('onclick').text(checkTip('您已经签名了'));
          localStorage.setItem(is_sign, 'true');
          $('.zhuan').removeClass('zhuanIng').addClass('zhuanEnd');
          $('.btnSig').addClass('btnSigEnd');
          isClick = true;
        }
      })
      .fail(function(e) {
        console.log(e.statusText);
      })
      .complete(function() {
      })
    }

    // 检查不同语言提示语
    function checkTip(info){
      var infos = info
      if(language !== 'zh'){
        switch(info){
          case '您已经签名了':
              infos = 'You have signed';
              break;
          case '已经签名过':
              infos = 'You have signed';
              break;
          case '签名失败,请刷新重试':
              infos = 'Failed. Please refresh and retry';
              break;
          case '您已签名,不可重复签名':
              infos = 'You’ve signed. Non-repeatable signature';
              break;
          case '你的网络签名的人太多,请稍后再试':
              infos = 'Too many requests from your intranet. Please retry later';
              break;
          case '签名失败':
              infos = 'Failed.';
              break;
          case '签名成功':
              infos = "You've signed";
              break;
          case '签名失败,您的网络存在频繁操作或作弊行为':
              infos = 'Failed. Frequent attempts or cheating behavior from your intranet';
              break;
          case '签名失败,您的网络或设备存在作弊行为':
              infos = 'Failed. Cheating behavior detected from your intranet or device';
              break;
        }
      }
      return infos;
    }

    // 点击签名
    $('.btnSig').click(function(event) {
      if(isClick){
        return false;
      }
      // $('.add1').removeClass('success');
      isClick = true;
      $('.zhuan').addClass('zhuanIng');
      var issign = localStorage.getItem(is_sign) ? localStorage.getItem(is_sign) : false ;
      issign = (issign === 'true') ? true : false;
      if(issign) {
        message1(checkTip("您已经签名了"));
        localStorage.setItem(is_sign, true);
        $('.zhuan').removeClass('zhuanIng').addClass('zhuanEnd');
        $('.btnSig').addClass('btnSigEnd');
        // $('.sign').removeAttr('onclick').text(checkTip('您已经签名了'));
        return false;
      }
      postRequest(visitorId);
      
    });

    // 签名-指纹
    function postRequest(fingerprint){
      $.ajax({
        url: '/api/v1/sign',
        type: 'POST',
        data: {"id":fgId,"fingerprint":fingerprint}
      })
      .done(function(res) {
        if(res.code === 0){
          $('.zhuan').fadeOut('200', function() {
            $('.zhuan').removeClass('zhuanIng').addClass('zhuanEnd').fadeIn();
            $('.btnSig').addClass('btnSigEnd');
            $('.add1').addClass('success');
          });
          localStorage.setItem(is_sign, true);
          changeEndNum += 1;
          if(changeNum === undefined){
            return false;
          }
          clock(changeNum, changeEndNum);
        }else{
          message1(checkTip(res.msg));
          $('.zhuan').removeClass('zhuanIng');
          if(res.code == -1){
            localStorage.setItem(is_sign, true);
            $('.zhuan').removeClass('zhuanIng').addClass('zhuanEnd');
            $('.btnSig').addClass('btnSigEnd');
          }else if(res.code == 400101){
            localStorage.setItem(is_sign, true);
            $('.zhuan').removeClass('zhuanIng').addClass('zhuanEnd');
            $('.btnSig').addClass('btnSigEnd');
          }else{
            isClick = false;
          }
        }
      })
      .fail(function(e) {
        console.log(e.statusText);
      })
      .complete(function() {
      })
    }


    // 语言切换
    $('.language').click(function(){
      if($(this).text() === '中文'){
          language = 'zh';
          $('.content').removeClass('content_en');
      }else{
          language = 'en';
          $('.content').addClass('content_en');
      }
      localStorage.setItem(language1, language);
      toggleLanguage(language);
      renders(language);
    });


    // 数字动效
    var currentTime = 25000000;
    var endTime = 25000000+100;
    var changeNum;
    var changeEndNum;
    var timerId1;
    var flagNum;
    // clock(currentTime, endTime);
    function clock(current, endTime) {
      updateTime();
      function updateTime() {
        var arrNum, seconds, minutes, hours, month, times = {};
        if(current > endTime){
          return false;
        }
        changeNum = current;
        changeEndNum = endTime;
        arrNum = (current + '').split('').reverse();
        for(var i = 0;i< arrNum.length; i++){
          times['num'+(i+1)] = arrNum[i];
        }
        // console.log(current,endTime,arrNum.length,times)
        // if(flagNum !== arrNum.length){
          // $('.time-container').show();
          // for(var i = arrNum.length;i< 11; i++){
          //   $('.num'+(i+1)).hide();
          // }
        // }

        flagNum = arrNum.length

        if(flagNum === 9){
          $('.time-container').show();
        }

        for (type in times) {
          if (times.hasOwnProperty(type)) {
            setTimes(type, times[type]);
          }
        }
        if(timerId1){
          clearTimeout(timerId1)
        }
        // console.log(changeNum,endTime)
        timerId1 = setTimeout(updateTime, 800);
        current++
      }

      function getPreviousTime(type) {
        return $('#' + type + '-top').text();
      }

      function setTimes(type, timeStr) {
        setTime(getPreviousTime(type + '-ones'),
          timeStr, type + '-ones');
      }

      function setTime(previousTime, newTime, type) {
        if (previousTime === newTime) {
          return;
        }
        setTimeout(function() {
          $('#' + type + '-top').text(newTime);
        }, 150);
        setTimeout(function() {
        $('.bottom-container',
          $('#' + type + '-bottom')).text(newTime);
        }, 365);

        animateTime(previousTime, newTime, type);
      }

      function animateTime(previousTime, newTime, type) {
        var top, bottom;
        top = $('#top-' + type + '-anim');
        bottom = $('#bottom-' + type + '-anim');
        $('.top-half-num', top).text(previousTime);
        $('.dropper', bottom).text(newTime);
        top.show();
        bottom.show();
        $('#top-' + type + '-anim').css('visibility', 'visible');
        $('#bottom-' + type + '-anim').css('visibility', 'visible');
        animateNumSwap(type);
        setTimeout(function() {
          hideNumSwap(type);
        }, 365);
      }

      function animateNumSwap(type) {
        $('#top-' + type + '-anim').toggleClass('up');
        $('#bottom-' + type + '-anim').toggleClass('down');
      }

      function hideNumSwap(type) {
        $('#top-' + type + '-anim').toggleClass('up');
        $('#bottom-' + type + '-anim').toggleClass('down');
        $('#top-' + type + '-anim').css('visibility', 'hidden');
        $('#bottom-' + type + '-anim').css('visibility', 'hidden');
      }
    }

    // 轮播图
    var isSlide;
    var mySwiper = new Swiper('.swiper',{
      autoplay : 3200,
      loop : true,
      spaceBetween : 30,
      autoplayDisableOnInteraction : false,
      pagination : '.swiper-pagination',
      onSlideChangeStart: function(swiper){
        isSlide = true;
      },
      onSlideChangeEnd: function(swiper){
        $('.swiper-slide .conts .packUp').click();
        isSlide = false;
      }
    });

    $('.swiper-slide h5').on("click", "span", function(e) {
      if(isSlide){
        return false;
      }
      $(this).hide();
      $(this).parent().siblings('.conts').show();
      $('.swiper-pagination').hide();
      mySwiper.lockSwipes();
      mySwiper.stopAutoplay();
    });
    $('.swiper-slide .conts .packUp').on("click", function(e) {
      $('.swiper-slide h5 span').show();
      $('.swiper-slide .conts').hide();
      $('.swiper-pagination').show();
      mySwiper.unlockSwipes();
      mySwiper.startAutoplay();
    });

    // 点击分享
    $('.circle .share').click(function(){
      $('html,body').height('100%');
      $('.closed,.closeInfo').show();
      $('.shareImg img').attr('src', $('.shareImg img').attr('data-src'));
      $('.content').css({
        'position': 'fixed',
        'opacity': '0',
        'z-index': '-100'
      });
      $('.shareImg').show().scroll(0,0);
    });
    $('i.closed').click(function(){
      $('html,body').height('auto');
      $('.closed,.closeInfo').hide();
      $('.shareImg').hide();
      $('.content').css({
        'position': 'relative',
        'opacity': '1',
        'z-index': '1'
      });
      mySwiper.startAutoplay();
      isSlide = false;
      // 开始轮播
    });

    // 每分钟取一次数据
    var timerId0;
    function perMinutes(){
      if(timerId0){
        clearInterval(timerId0);
      }
      timerId0 = setInterval(startMarqueue,60000);
    }

    function startMarqueue(){
      $.ajax({
        url: '/api/v1/num',
        type: 'get'
      })
      .done(function(res) {
        if(res.code == 0){
          res.data = res.data ? res.data: {total: null};
          res.num = res.data.total == null ? 0 : res.data.total;
          changeEndNum = parseInt(res.num);
          clock(changeNum, changeEndNum);
        }
      })
      .fail(function(e) {
        console.log(e.statusText);
      });
    }

    // 获取信息
    var flagInfo = $('#fable').html();
    function getInfo(){
      $.ajax({
        url: '/api/v1/info',
        type: 'get'
      })
      .done(function(res) {
        if(res.code == 0){
          res.data = res.data ? res.data: {total: null};
          res.num = res.data.total == null ? 0 : res.data.total;
          $('#num').text(res.num);

          if(!res.data.cities){
            return false;
          }
          var data = res.data.cities;
          var arr = data;
          function compare(property){
              return function(a,b){
                  var value1 = a[property];
                  var value2 = b[property];
                  return value2 - value1;
              }
          }
          data = arr.sort(compare('time'));
          var html = '';
          var current_stamp = Date.parse(new Date())/1000;
          for(var i=0; i<data.length;i++  ){
              var diff = parseInt(current_stamp-data[i].time);
              if(diff<=0){
                diff = 1;
              }
              var timestr = '';
              if(diff<60) timestr = diff+'秒前';
              if(diff>=60 && diff<3600) timestr = Math.floor(diff/60) +'分钟前';
              if(diff>=3600 && diff<86400) timestr = Math.floor(diff/3600)+'小时前';
              if(diff>=86400 && diff<2592000) timestr = Math.floor(diff/86400)+'天前';
              if(diff>=2592000 && diff<31104000) timestr = Math.floor(diff/2592000)+'月前';
              if(diff>=31104000) timestr = Math.floor(diff/31104000)+'年前';
              html+="<h4><i class='iconcs'></i><p><span class='textspan'>来自"+data[i].city+"的网友参加了签名</span><span class='minutespan' >"+timestr+"</span></p></h4>";
          }
          $('#fable').html(flagInfo);
          $('#box').empty().append(html);
          marque(175,148,'fable','box');
          currentTime = res.num || 25000000;
          if(changeNum){
            // console.log('切换获取getInfo')
            if(currentTime > changeEndNum){
              clock(changeNum, currentTime);
              return false;
            }
            clock(changeNum, changeEndNum);
          }else{
            // console.log('获取getInfo')
            if(currentTime<100){
              clock(currentTime-20, currentTime);
              return false;
            }
            clock(currentTime-100, currentTime);
          }
          // console.log('getInfo',currentTime, changeNum,changeEndNum);
        }
      })
      .fail(function(e) {
        console.log(e.statusText);
      })
    }
    // 网友滚动
    // 滚动
    var scrollElem;
    var stopscroll;
    var stoptime;
    var preTop;
    var leftElem;
    var currentTop;
    var marqueesHeight;
    var timerId3;
    var timerId2;
    function marque(width,height,marqueName,marqueCName){
      try{
        marqueesHeight = height;
        stopscroll     = false;
        scrollElem = document.getElementById(marqueName);
        with(scrollElem)
        {
          style.width     = width;
          style.height    = marqueesHeight;
          style.overflow  = 'hidden';
          noWrap          = true;
          align           = 'left';
        }
        preTop     = 0;
        currentTop = 0;
        stoptime   = 0;
        leftElem = document.getElementById(marqueCName);
        scrollElem.appendChild(leftElem.cloneNode(true));

        if(timerId3){
          clearTimeout(timerId3);
        }
        timerId3 = setTimeout("init_srolltext()",1000);
      }catch(e) {}
    }
    function init_srolltext(){
      scrollElem.scrollTop = 0;
      if(timerId2){
        clearTimeout(timerId2);
      }
      timerId2 = setInterval('scrollUp()', 30);
    }
    function scrollUp(){
      if(stopscroll) return;
      currentTop += 1;
      if(currentTop == marqueesHeight+1){
        stoptime += 1;
        currentTop -= 1;
        if(stoptime == 1) {
          currentTop = 0;
          stoptime = 0;
        }
      }else{
        preTop = scrollElem.scrollTop;
        scrollElem.scrollTop += 2;
        if(preTop == scrollElem.scrollTop){
          scrollElem.scrollTop = marqueesHeight;
          scrollElem.scrollTop += 2;
        }
      }
    }

    // 弹框封装
    function messageShow1() {
        var w = $('.message1');
        w.addClass('messageShow');
    };
    function messageHide1() {
        var w = $('.message1');
        w.removeClass('messageShow').removeClass('messageShowNavFix');
    };
    function messageOut1() {
        var w = $('.message1');
        w.css('display', 'none');
        w.html('');
    };
    var t1, t2, t3;
    function message1(str) {
        var w = $('.message1');
        clearTimeout(t1);
        clearTimeout(t2);
        clearTimeout(t3);
        w.html(str);
        w.css('display', 'block');
        t1 = setTimeout("messageShow1()", 80);
        t2 = setTimeout("messageHide1()", 2500);
        t3 = setTimeout("messageOut1()", 3000);
    };

     

    • “当然后台的数据,就没人知道了”。这究竟是在洗地呢,还是在高级黑? +9
      • 科学 +5
        • 这不叫科学,叫技术! +8
          • 本着科学的态度讨论技术 +3
            • 博士啊,就这话还贴边,其它都太离谱了。 +3
              • computer science你说是科学还是技术啊,都有哈 +2
                • computer science翻译成科学,你的那段叫技术!博士啊,你也分得清科学和技术,要不就白拿博士了。 +6
                  • 当然,所以我说本着科学的态度 +3
                    • 用实事求是的态度就可以了,其它有些扯。 +4
        • 那个不断在滚动的数字,不仅是为了吸引眼球,而是在塑造一种气势,一种支持者络绎不绝的气势,让反对者垂头丧气,是洗脑战心理战的高级形式。 +5
    • 为啥做个"吸引眼球"的动画,实际上投票数字并没有那么发生,不是骗人么。 +16
      • 如果你用我提到的ajax url拿后台数据,其实是比显示的高,这么搞和国内节庆销售网站一样,就是搞个气氛督促赶快投,数字并不是实时数据 +4
        • 当真是如此的话,应该加个注解。 +2
          • 其实注解了 +3
            • 嘿嘿,大家都是明白人,只有你能看到的注解… +6
              • 自己看 +4


                :

                • 你是明显自己没看懂啊,LOL。 +3
        • 当然后台的数据,就没人知道了。 +3
        • 上面的数据,是假数据? +2
          • 短时间往上加是动画效果,但是网页每60秒更新实时数据 +2
        • 那就应该用ajax更新数据,而不应该做这个假的动画。又不是没数据,真是令人无语。 +3
          • 如果技术讨论的话,每次ajax拿的数字都是一个数字,无法做到数字一个个增加的效果啊,也没人一秒来一次ajax call,后台不宕了 +3
      • 天朝大外宣骗人,难道很奇怪么? 应该说,现在还看环球时报这种大外宣的,活该被骗。 +9
    • 我也希望赶紧把孟送回去,请神容易送神难,留在这里就是浪费纳税人的钱 +5
      • 人不想回去 +3
        • 还真有可能,和当年老赖一样。胡大侠岂不是一厢情愿? +1
      • 觉得老胡应该问问孟本人的意见。
        • 搭不上话呀,老胡真不称钱,人也不精神。
    • 这种签名有个P用, 你鼓动14亿人签名就能让别国听你的?有本事把国内的政策也签名一次? +5