微信浏览器开发,后退时强制刷新的解决方案 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
Aether
V2EX    程序员

微信浏览器开发,后退时强制刷新的解决方案

  •  
  •   Aether
    aetherwu 2016-11-21 19:35:54 +08:00 22350 次点击
    这是一个创建于 3265 天前的主题,其中的信息可能已经有所发展或是发生改变。
    和这破事儿逗逼了三天,试过各种办法,包括而不限于 onpopstate/onpageshow/ onload ,也试过本地数据缓存读写,还用过 AJAX 更新,都可耻地失败了很神奇的是,在 Andorid 和微信自家的模拟器上都有效果,唯独在 iOS 的浏览器上失败。

    我想要的很简单,就是当 Javascript 调用 history.back() 或者 history.go(-1) 时,微信浏览器可以自动刷新前面调用过的历史页面。而在 iOS 的微信上,唯独 location='' location.href='' history.go(0) 这几句就是死活无效。

    最后被逼无赖,解决方案还是要靠 URL 上的随机数,也就是在当前打开的页面添加随机数:

    var rnumber = Math.floor(Math.random()*1000)
    history.replaceState({mod: rnumber}, 'Title', '?mod='+rnumber);

    然后下一个页面调用 history.back() 回来的时候,这个代码会生成新的 URL ,从而强制微信判断为不同的页面,达到强制刷新的目的。

    完成这个技术 hack 的目标是,在 Web page (纯页面,非 Web app )的体系内,保持友好的「返回」体验,否则在页面上填写一个表单,点击提交以后,点击「返回」会返回填写表单的界面。虽然在逻辑上这里也没错,但是现在的体验都在向 APP 靠拢,故有此一折腾。。。


    细节描述:
    1 、在当前 view 添加随机值,可以动态判断,仅对编辑者有效:
    var rnumber = Math.floor(Math.random()*1000)
    history.replaceState({mod: rnumber}, 'Title', '?mod='+rnumber);

    2 、用户点击进入编辑页面(无变化)

    3 、在 POST 后的编辑页面输出
    history.go(-2)
    将浏览历史回退

    4 、前述的第一个页面会因为 Javascript 的原因生成新的随机 URL ,导致微信浏览器识别为新的资源而强制刷新,从而加载编辑后的新内容。

    5 、此时用户点击左上角「返回」,会按原路返回「上一级」(而不是 Web page 中的上一页概念)。

    此方案在我手边的环境里测试有效(但不能担保对所有特别是对安卓全阵营有效)。
    网上没找到特别明确的解决方案,所以这里特别记录分享一下,也许会对其他朋友有用。
    第 1 条附言    2016-12-26 16:17:12 +08:00
    我更新一下。。。发现随机数会导致分享 SDK 的签名失效(一脸懵逼)
    第 2 条附言    2016-12-27 12:36:30 +08:00

    这是35天后的一个更新(第一个 APPEND 是昨天,这是第二个)

    现在我去掉了随机数,因为必须保证微信分享 SDK 验证过关,而我不想在本地 JS 做校验(其实是懒得改/也没有必要每次刷新都做一次)。 我现在的做法:

    1、统一跳转到一个 backstep.html 的模板页面 2、backstep 写入本地 localStorage,值为希望回退的步数(比如2或者3) 3、然后通过 location.replace 将一个目标页面刷新:

    比如:

    localStorage.setItem("back2steps", "{{backsteps|default(2)}}"); location.replace("{{url}}") 

    4、在新的页面,读取 localStorage 并且将其重置为空 5、如果读取到 localStorage 数字,那么将 history 调回 N 步,这个时候因为此页面已经在当前刷新过了,所以看上去就是刷新过的。

    例如:

    window.Onpageshow= function(){ detectBackStes = parseInt(localStorage.getItem("back2steps")); if(detectBackStes>0){ localStorage.setItem("back2steps", ""); window.scrollTo(0,1) history.go(-detectBackStes); } } 

    以上,非常脏的做法,用户可能会有轻微的闪烁感(如果页面很轻则可能感觉不出来)。 但至少实现了我现在想要的部分目标。

    我还是应该实际些。。。考虑去开 VUEJS 技能点 T_T

    9 条回复    2016-12-24 19:56:33 +08:00
    jininij
        1
    jininij  
       2016-11-22 00:25:56 +08:00 via Android
    之前也被这问题困扰了一整天,最后不得不以一个特别变态的方法实现:用 js 拦截所有 a 跳转,并复写 window.location 。如果页面试图跳转,就往 localStorage 里记录一下,再主动去跳转。然后用定时循环不断检查 localStorage 。
    写回复的时候突然又想到一个方法,页面到后台后, setTimeout 会被暂停,而微信的页面只能现实一个窗口,所以针对其他多窗口的浏览器,页面不在活动页面时 setTimeout 优化不会发生在微信上。这一点也可以用来 hack 一下。
    DreGD
        2
    DreGD  
       2016-11-22 08:57:18 +08:00 via Android
    同加过随机数
    DreGD
        3
    DreGD  
       2016-11-22 08:58:46 +08:00 via Android
    依稀记得是 200 from cache 而不是 304
    leohxj
        4
    leohxj  
       2016-11-22 13:32:30 +08:00
    浏览器有一个机制叫做 Back-Forward Cache : https://developer.mozilla.org/en-US/docs/Working_with_BFCache
    不知道是否有帮助。
    nosun
        5
    nosun  
       2016-12-24 18:25:11 +08:00
    按照楼主的方案,试了下,没成功,返回之后页面没强制刷新,能看到 url 上退回去的时候随机数变了。

    怎么破,就是想在使用手机的后退按钮返回时,需要强制刷新页面。否则页面是空白的。
    Aether
        6
    Aether  
    OP
       2016-12-24 19:15:47 +08:00
    @nosun 什么系统?什么浏览器?微信版本号?手机的后退按钮要比程序回退应该要简单些,你测试一下 onpageshow 部分?
    nosun
        7
    nosun  
       2016-12-24 19:47:37 +08:00
    安卓 6.0 微信 6.3.32 , 浏览器不知道怎么看
    nosun
        8
    nosun  
       2016-12-24 19:50:01 +08:00
    我这边是在微信中嵌入了一个 web 页面,中间是 ajax 加载了一些数据,现在后退了, ajax 那部分不响应,主要是这个问题,试过 ajax + 时间戳, cache 设置为 false 都不管用。手动刷新一下就可以。在微信的模拟器中也是这样。
    nosun
        9
    nosun  
       2016-12-24 19:56:33 +08:00
    嗯,我再看看
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1026 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 18:42 PVG 02:42 LAX 11:42 JFK 14:42
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86