Javascript 能否检测到 POST 操作已完成?
Can Javascript detect that a POST operation is completed?
我正在使用 Chrome 扩展,它旨在让用户更好地控制我们大学对 Drupal CMS 的页面之间的导航。我希望能够影响的事情之一是执行保存操作后页面导航的位置。保存由 <form>
元素处理,这些元素使用 POST 方法并将其 action
属性设置为与当前页面相同的 URL 。但是,根据当前页面的类型,保存操作(单击 <input type="submit">
元素)将导致导航到另一个页面,或者使页面保留在同一位置。我希望用户应该能够 select 通过从我在扩展中添加的 <select>
元素中选择一个选项来保存后导航到哪个页面。这导致 chrome.storage 对象存储所需的目标 URL,然后在 window.addEventListener("beforeunload")
函数中检索该目标,然后执行 window.location.href = <desired URL>
。为了显示保存的内容,还必须重新加载页面。
对我来说,仅从客户端工作的问题是知道何时指向 selected 位置。如果它发生得太快,则保存操作不会完成。如果发生得太晚,默认页面有时间加载,时间就浪费了。我设法通过插入 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
});
这个答案没有提供检测 POST 操作是否完成的方法——而是使用 AJAX 劫持了 post 操作。但它完成了我想到的任务,即将表单数据的发送与到下一页的导航分开。
基于 wOxxOm's comment, I have got the following procedure to work, using the 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
});
});
我正在使用 Chrome 扩展,它旨在让用户更好地控制我们大学对 Drupal CMS 的页面之间的导航。我希望能够影响的事情之一是执行保存操作后页面导航的位置。保存由 <form>
元素处理,这些元素使用 POST 方法并将其 action
属性设置为与当前页面相同的 URL 。但是,根据当前页面的类型,保存操作(单击 <input type="submit">
元素)将导致导航到另一个页面,或者使页面保留在同一位置。我希望用户应该能够 select 通过从我在扩展中添加的 <select>
元素中选择一个选项来保存后导航到哪个页面。这导致 chrome.storage 对象存储所需的目标 URL,然后在 window.addEventListener("beforeunload")
函数中检索该目标,然后执行 window.location.href = <desired URL>
。为了显示保存的内容,还必须重新加载页面。
对我来说,仅从客户端工作的问题是知道何时指向 selected 位置。如果它发生得太快,则保存操作不会完成。如果发生得太晚,默认页面有时间加载,时间就浪费了。我设法通过插入 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
});
这个答案没有提供检测 POST 操作是否完成的方法——而是使用 AJAX 劫持了 post 操作。但它完成了我想到的任务,即将表单数据的发送与到下一页的导航分开。
基于 wOxxOm's comment, I have got the following procedure to work, using the 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
});
});