0%

使用 iframe 避免表单刷新时的重复提交

使用同步方式提交表单时最郁闷的事情就是刷新时表单重复提交了,一次重复提交以后,后续做各种操作(reset 表单、删除表单都不奏效)都很难避免,搜了一下网上的答案,无外乎以下两种:

  1. 改为 AJAX 进行表单交互;
  2. 改进服务端,使用一个中转页面进行 redirect

然而很多时候我们并不能去修改服务端(比如没有权限,或者后端功能已经趋于稳定、修改成本高),那么这样就不能避免重复提交了吗?于是我根据页面中转的思路使用 iframe 做了一次尝试,果然页面就不会重复提交了,方法如下:

  1. 为页面添加一个隐藏的 iframe(假设 css 中 .hide 的样式已经设置为了 display:none )

  2. 将 form 的 target 绑定到 iframe 上

    // 表单内容

  3. 编写 JS 绑定相关事件

    document.addEventListener(‘DOMContentLoaded’, function(){
    var form = document.querySelector(‘#form’),
    iframe = document.querySelector(‘#iframe’),
    href = window.location.href;
    iframe.setAttribute(‘src’, href); // 设置 iframe 加载当前地址栏的页面(因为有一些表单提交时会验证 url)
    // 绑定表单提交事件
    form.addEventListener(‘submit’, function(event) {

    // 当表单提交时,为 iframe 绑定 load 事件,
    // 当 iframe 中页面加载完毕(提交成功时,跳转当前页面为当前 url,替代刷新效果)
    iframe.addEventListener('load', function(event) {
      window.location = window.location.href;
    }, false);

    }, false);
    }, false);

这个逻辑的精髓在于,使用了一个 iframe 充当中间跳转页面的角色,在不需要修改后端代码的情况下既可以避开页面刷新重复提交了。当然,如果页面提交后,会有某些提示信息,也可以在 iframe 的 load 事件中进行监测,获取相应字符串以后再判断接下来做什么。获取 iframe 中的内容方法如下(以 body 为例):

var iframeDocument = iframe.contentDocument || iframe.contentWindow.document,
ibody = iframeDocument.body;
console.log(ibody.textContent); // 打印 iframe 中 body 里所有的文本内容