首页 > 解决方案 > Javascript 可以检测到 POST 操作已完成吗?

问题描述

我正在使用 Chrome 扩展程序,该扩展程序旨在让用户对我们大学改编的 Drupal CMS 中的页面之间的导航有更多的控制。我希望能够影响的一件事是执行保存操作后页面导航的位置。保存由<form>使用 POST 方法的元素处理,并将其action属性设置为与当前页面相同的 URL。但是,根据当前页面的类型,保存操作(单击<input type="submit">元素)将导致导航到另一个页面,或者页面保持在同一位置。我希望用户应该能够在保存后通过选择一个选项来选择要导航到的页面<select>我在扩展中添加的元素。这会导致 chrome.storage 对象存储所需的目标 URL,然后在执行 a 的window.addEventListener("beforeunload")函数中检索该目标 URL window.location.href = <desired URL>。为了显示保存的内容,还必须重新加载页面。

对我来说,仅从客户端工作的问题是知道何时定向到所选位置。如果它发生得太快,则保存操作未完成。如果它发生得太晚,默认页面有时间加载,时间就会丢失。我已经设法通过插入一个函数使其临时工作setTimeout(),但是超时间隔当然是任意的,并且可能会根据很多情况而失败。有没有办法在 js 脚本中检测到 POST 操作已完成并且现在可以安全地加载新页面?

现在的代码:

HTML

<select class="my-selector">
  <option value="URL1">page 1</option>
  <option value="URL2">page 2</option>
  <!--etc -->
</select>

JS

 $(".my-selector").change(function(){
      var url = $(this).val();
      chrome.storage.sync.set({redirect:true,url:url})
      $(this).closest("form").submit();
 });

    //=============

    window.addEventListener("beforeunload", function() {
       chrome.storage.sync.get(function(message){
          if(message.redirect){
            chrome.storage.sync.set({redirect:false,reload:true});
            setTimeout(function(){ //this I want to avoid
              window.location.href = message.url;
            },3000);  
          }
        })
      });

    //=============

$(document).ready(function(){
      chrome.storage.sync.get(function(message){
          if(message.reload){
            chrome.storage.sync.set({reload:false});
            location.reload();
          }
      });
     //etc
 });

标签: javascriptjquerygoogle-chrome-extensiondrupal

解决方案


这个答案没有提供一种检测 POST 操作是否完成的方法——而是使用 AJAX 劫持了 post 操作。但它完成了我心目中的任务,即将表单数据的发送与导航分离到下一页。基于wOxxOm

评论中的出色建议,我使用FormData API和 jQuery操作完成了以下过程。我不知道它是否是最优的——是否有更直接的方法来创建对象?欢迎任何建议。$.post()formObj

HTML

<select class="my-selector">
  <option value="URL1">page 1</option>
  <option value="URL2">page 2</option>
  <!--etc -->
</select>

JS

$(".my-selector").change(function(){
   var link = $(this).val();
   var myForm = $(this).closest("form").get(0);//select the form
   var url = $(myForm).attr("action");
   var formData = new FormData(myForm);//use FormData API to extract the data to send
   var formObj = {};
   for(var pair of formData.entries()){
      formObj[pair[0]] = pair[1];//create the object to send the data with
   }
   $.post(url,formObj,function(){ //send the data without submitting the form
      window.location.href = link; //redirect to desired location
   });
 });

推荐阅读