写点什么

解决浏览器回退表单重复提交问题

作者:沃德
  • 2022 年 7 月 13 日
  • 本文字数:5182 字

    阅读完需:约 17 分钟

暂时没有别的什么好办法,在网上搜索到用 sessionStorage+ajax 形式请求数据来避免浏览器回退表单重复提交.


首先页面展示为订单列表,分为三个 tab,为未支付订单,已支付订单,过期订单,在列表里点击一个 item 时进入订单详情页,回退后要求效果为还停留在原来的 tab,列表位置也要在选中位置。


  <div class="mainBody" style="height: auto">    <div class="mainBodyBack">        <div class="orderSelection">            <div class="orderSelectionTags">                <div id="waitPayId" class="orderButtonInsurance orderButtonInsuranceBack">待支付                    <div class="underLine show"></div>                </div>                <div id="hasPayId" class="orderButtonInsurance">已支付                    <div class="underLine"></div>                </div>                <div id="overdateId" class="orderButtonInsurance">已过期                    <div class="underLine"></div>                </div>            </div>        </div>
<%--待支付--%> <div class="orderListBack show" id="orderWaitPay"> </div>
<%--已支付--%> <div class="orderListBack" id="orderHasPay"> </div>
<%--已过期--%> <div class="orderListBack" id="orderoverDate"> </div> </div></div>
复制代码


原来的实现方式时直接在 waitPayId,hasPayId,overdateId 三个 div 中填充数据,现在要修改为用 ajax 请求的方式进行填充。


ajax 请求的部分代码为:


function getOrderListData() {        dismissAlertAction()        $.ajax({            url: "${ctx}/order/getOrderList",            type: "POST",            data: {},            dataType: "json",            success: function (resp) {                if (resp.code === 0) {                    console.info(resp.data)                    //未支付订单列表                    var listUnPaidOrder = new Array();                    listUnPaidOrder = resp.data[0];                    //已只读订单列表                    var listPaidOrder = new Array();                    listPaidOrder = resp.data[1];                    //过期订单列表                    var listOverDateOrder = new Array();                    listOverDateOrder = resp.data[2];                    console.info(listUnPaidOrder.length)                    console.info(listPaidOrder.length)                    console.info(listOverDateOrder.length)
window.sessionStorage.setItem("listUnPaidOrder", JSON.stringify(listUnPaidOrder)); window.sessionStorage.setItem("listPaidOrder", JSON.stringify(listPaidOrder)); window.sessionStorage.setItem("listOverDateOrder", JSON.stringify(listOverDateOrder));
fillDataView(listUnPaidOrder, listPaidOrder, listOverDateOrder); } } }); }
复制代码


页面加载自动调用的 js 代码为


   //当前切换的tab值    var titleTab = window.sessionStorage.getItem("titleTab");    if (titleTab == null || titleTab == "") {        titleTab = 0;    }    var currentTab = titleTab;
function setHeight() { $("html,body").css("height","100%"); } function fillDataView(listUnPaidOrder, listPaidOrder, listOverDateOrder) { var divUnPaidOrder = ""; //未支付订单列表 if (listUnPaidOrder.length == 0) { setHeight() divUnPaidOrder += '<div class="orderNoneBack" id="orderWaitPay"> <div class="orderListEmpty"> <img src="${ctx}/resources/img/noOrder.png" alt=""/> <div class="orderListEmptyText">您还没有相关订单记录</div> </div> </div>'; } else { for (var i = 0; i < listUnPaidOrder.length; i++) { var orderDto = listUnPaidOrder[i]; divUnPaidOrder += ' <div class="orderClass"> <div class="orderClassHeader">' + ' <div class="orderClassDate">' + orderDto.createOrderTime + '</div>' + ' <div class="orderDetailButton" onclick="goToOrderDetail(' + orderDto.id + ')">查看详情 </div> ' + '</div> <div class="orderInformation"> <div class="orderImg"> <div class="orderHeadImg insurance_' + orderDto.insuCom + '"> </div> ' + '</div> <div class="orderInsurance"> <div class="orderInsurnceText">' + orderDto.insuComName + '</div> ' + '<div class="orderInsurnceText lightColor">共投保 ' + orderDto.coverageCount + '种保险</div> ' + '</div> <div class="orderBuyer"> <div class="orderInsurnceText">' + orderDto.licenseNo + '</div> ' + '<div class="orderInsurnceText">' + orderDto.insuredName + '</div> </div> </div> <div class="orderFooter">' + ' <div class="left-apart">实付款:<span class="moneyColor">' + (orderDto.sumAmount / 100).toFixed(2) + '元</span>' + ' </div> <div class="right-apart" ' + 'onclick="payAtOnece('+orderDto.id+')">立即支付 </div> </div> </div>'; } } $("#orderWaitPay").html(divUnPaidOrder); var divPaidOrder = ""; //已支付订单列表 if (listPaidOrder.length == 0) { setHeight() divPaidOrder = '<div class="orderNoneBack" id="orderWaitPay"> <div class="orderListEmpty"> <img src="${ctx}/resources/img/noOrder.png" alt=""/> <div class="orderListEmptyText">您还没有相关订单记录</div> </div> </div>'; } else { for (var i = 0; i < listPaidOrder.length; i++) { var orderPaidDto = listPaidOrder[i]; divPaidOrder += '<div class="orderClass"> <div class="orderClassHeader"> ' + '<div class="orderClassDate">' + orderPaidDto.createOrderTime + '</div>' + ' <div class="orderDetailButton" ' + 'onclick=" goToOrderDetail(' + orderPaidDto.id + ')">' + '查看详情 ' + '</div> </div>' + ' <div class="orderInformation">' + ' <div class="orderImg"> ' + '<div class="orderHeadImg insurance_' + orderPaidDto.insuCom + '">' + ' </div> </div> ' + '<div class="orderInsurance"> ' + '<div class="orderInsurnceText">' + orderPaidDto.insuComName + '</div> ' + '<div class="orderInsurnceText lightColor">' + '共投保' + orderPaidDto.coverageCount + '种保险</div>' + ' </div> <div class="orderBuyer">' + ' <div class="orderInsurnceText">' + orderPaidDto.licenseNo + '</div> <div class="orderInsurnceText">' + orderPaidDto.insuredName + '</div> </div> ' + '</div> <div class="orderFooter">实付款:<span class="moneyColor">' + (orderPaidDto.sumAmount / 100).toFixed(2) + '元</span> ' + '</div> </div>'; } } $("#orderHasPay").html(divPaidOrder);
var divOverDateOrder = ""; //已过期订单列表 if (listOverDateOrder.length == 0) { setHeight() divOverDateOrder = '<div class="orderNoneBack" id="orderWaitPay"> <div class="orderListEmpty"> <img src="${ctx}/resources/img/noOrder.png" alt=""/> <div class="orderListEmptyText">您还没有相关订单记录</div> </div> </div>'; } else { for (var i = 0; i < listOverDateOrder.length; i++) { var orderOverDateDto = listOverDateOrder[i]; divOverDateOrder += ' <div class="orderClass"> <div class="orderClassHeader">' + ' <div class="orderClassDate">' + orderOverDateDto.createOrderTime + '</div> ' + '<div class="orderDetailButton" onclick="goToOrderDetail(' + orderOverDateDto.id + ')">查看详情 </div>' + ' </div> <div class="orderInformation"> <div class="orderImg"> <div class="orderHeadImg insurance_' + orderOverDateDto.insuCom + '"> </div> ' + '</div> <div class="orderInsurance"> <div class="orderInsurnceText">' + orderOverDateDto.insuComName + '</div> <div class="orderInsurnceText lightColor">' + '共投保' + orderOverDateDto.coverageCount + '种保险</div> </div> <div class="orderBuyer"> ' + '<div class="orderInsurnceText">' + orderOverDateDto.licenseNo + '</div> ' + '<div class="orderInsurnceText">' + orderOverDateDto.insuredName + '</div> </div>' + ' </div> <div class="orderFooter"> <div class="left-apart">实付款:<span class="moneyColor">' + (orderOverDateDto.sumAmount / 100).toFixed(2) + '元</span>' + ' </div> <div class="right-apart"' + 'onclick=" reQuotePrice(' + orderOverDateDto.id + ')">重新报价 </div>' + ' <div class="right-apart margin-right-jt"' + ' onclick=" cancelOrder(' + orderOverDateDto.id + ')">删除订单 </div> </div> </div>'; } } $("#orderoverDate").html(divOverDateOrder); }
复制代码


大概就是浏览器回退再次调用 ajax 请求的时候判断是否已经调用过,标记保存在 sessionStorage 里面,这里说下 sessionStorage,了解到 sessionStorage 用于存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。所以 sessionStorage 不是一种持久化的本地存储,仅仅是会话级存储方式。而 localStorage 用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。


Web Storage 的概念和 cookie 相似,区别是它是为了更大容量存储设计的。Cookie 的大小是受限的,并且每次你请求一个新的页面的时候 Cookie 都会被发送过去,这样无形中浪费了带宽,另外 cookie 还需要指定作用域,不可以跨域调用。


除此之外,Web Storage 拥有 setItem,getItem,removeItem,clear 等方法,不像 cookie 需要前端开发者自己封装 setCookie,getCookie。


但是 Cookie 也是不可以或缺的:Cookie 的作用是与服务器进行交互,作为 HTTP 规范的一部分而存在 ,而 Web Storage 仅仅是为了在本地“存储”数据而生。


localStorage 和 sessionStorage 都具有相同的操作方法,例如 setItem、getItem,removeItem,clear 等.


之前的做法是把这个标志位存储到服务器端,比如存入 redis 在记录,但是比较来说存储到 redis 的形势不仅对服务器压力大,而且会影响到业务逻辑实现等等,这样单页面 session 会话级别存储更清晰一些。

用户头像

沃德

关注

我就是个零 2018.06.14 加入

程序员而已

评论

发布
暂无评论
解决浏览器回退表单重复提交问题_程序员_沃德_InfoQ写作社区