如何捕获 form.submit 的响应

IT技术 javascript forms dom-events form-submit
2021-01-28 01:49:58

我有以下代码:

<script type="text/javascript">
        function SubmitForm()
        {

            form1.submit();
        }

        function ShowResponse()
        {

        }
</script>
.
.
.
<div>
    <a href="#" onclick="SubmitForm();">Click</a>
</div>

我想捕获form1.submit? 我该怎么做呢?我可以向 form1.submit 方法注册任何回调函数吗?

6个回答

您将无法使用普通的 javascript 轻松做到这一点。当您发布表单时,表单输入将发送到服务器并刷新您的页面 - 数据在服务器端处理。也就是说,该submit()函数实际上并不返回任何内容,它只是将表单数据发送到服务器。

如果您真的想在 Javascript 中获得响应(不刷新页面),那么您将需要使用 AJAX,而当您开始谈论使用 AJAX 时,您将需要使用一个库。jQuery是迄今为止最受欢迎的,也是我个人的最爱。有一个很棒的 jQuery 插件叫做Form,它可以完全按照你的要求做。

以下是您如何使用 jQuery 和该插件:

$('#myForm')
    .ajaxForm({
        url : 'myscript.php', // or whatever
        dataType : 'json',
        success : function (response) {
            alert("The server says: " + response);
        }
    })
;
我发布此评论更多是作为上述解决方案有效的仅供参考,但在 IE 9 及更低版本上通过 AJAX 上传文件时除外。我在非 HTML5 IE 浏览器(IE 9 及更低版本)上通过 ajax 提交文件时遇到问题,所以我必须使用 iframe hack。但是使用 iframe hack 需要 form.submit(),但是您不能等待响应来告诉您它是否成功。这让我陷入了困境。
2021-03-13 01:49:58
在这里使用图书馆真的不值得。在纯 JS 中,代码并不复杂:var xhr = new XMLHttpRequest() xhr.open("POST", "myscript.php"); xhr.onload=function(event){ alert("The server says: " + event.target.response); }; var formData = new FormData(document.getElementById("myForm")); xhr.send(formData);
2021-03-19 01:49:58
+1 用于 jQuery 表单插件。太棒了,但你把“目标”属性弄错了。它不像表单的 'action' 属性;即它不是提交目的地。来自文档目标 - 标识页面中要使用服务器响应更新的元素。
2021-03-20 01:49:58
公平地说,您不需要为 AJAX 使用库。库是使用 javascript 编写的,因此存在非库解决方案。也就是说,我 100% 赞成使用库来抽象进行 AJAX 调用所涉及的所有荒谬和复杂性。
2021-03-26 01:49:58

Ajax 的替代方法是将一个 invisible 设置<iframe>为表单的目标,并<iframe>在其onload处理程序中读取其内容但是当有 Ajax 时,为什么还要麻烦呢?

注意:我只是想提一下这个替代方案,因为有些答案声称没有 Ajax不可能实现这一点。

@Dropped.on.Caprica 是的,这仍然是<iframe>POST的合法用例(回调到parent)。对于下载和上传等...
2021-03-15 01:49:58
假设您是否想通过单击按钮发布到 URL 进行下载?现在您不能将 Ajax 用于您的请求。想在下载完成后清理或更新界面?现在是时候从Ajax的 POST 中获得回调了(死尸,我知道。)
2021-03-23 01:49:58
为了检测下载是否成功,我最近学到的一个巧妙技巧是在下载响应中设置一个 cookie 并轮询浏览器中该 cookie 的存在。
2021-03-27 01:49:58
请注意,这仅在表单提交操作与 iframe 位于同一站点时才有效。否则同源策略将阻止它。
2021-03-27 01:49:58
此外,据我所知,对于需要与旧版本 IE (7+) 兼容的任何人,我很确定 iframe 方法是唯一的出路。如果我错了,请纠正我,因为我现在遇到了这个问题。
2021-03-28 01:49:58

非 jQuery vanilla Javascript 方式,摘自 12me21 的评论:

var xhr = new XMLHttpRequest();
xhr.open("POST", "/your/url/name.php"); 
xhr.onload = function(event){ 
    alert("Success, server responded with: " + event.target.response); // raw response
}; 
// or onerror, onabort
var formData = new FormData(document.getElementById("myForm")); 
xhr.send(formData);

ForPOST的默认内容类型是“application/x-www-form-urlencoded”,它与我们在上面的代码片段中发送的内容相匹配。如果您想发送“其他内容”或以某种方式对其进行调整,请参阅此处了解一些细节。

@Randy 就我而言,我在表单中有一个这样的按钮,<input type='button' onclick="submitForm(); return false;">或者您可以为“提交”事件添加一个事件侦听器,例如 Marcus 的答案:stackoverflow.com/a/51730069/32453
2021-03-24 01:49:58
这对我来说是完美的。我正在编写一个 chrome 插件,并试图避免使用任何库,而是在服务器上处理更复杂的操作。这非常适合我的需要 谢谢!
2021-03-25 01:49:58
这看起来正是我所需要的,因为我已经有一个 PHP 文件,它在我的页面上处理许多直接的 XMLHttpRequest()。但是对于带有典型 <form action = "/mysite/mycode.php"> 和 <submit> 标签的简单表单,我不确定如何修改.. 我会用一个回调,) 如:<form action="myhttpreq("url, etc...)? 或者也许 <form action="#" onsubmit="return myhttpfunction() ?类似的东西?如果它那么简单,这绝对是答案。但我有点困惑如何设置它。
2021-04-05 01:49:58
其实这才是正确答案!因为所有其他答案都完全相同,但被另一层库混淆了。
2021-04-08 01:49:58

未来的互联网搜索者:

对于新的浏览器(截至 2018 年:Chrome、Firefox、Safari、Opera、Edge 和大多数移动浏览器,但不是 IE),fetch是一个标准 API,用于简化异步网络调用(我们过去需要XMLHttpRequest或 jQuery 的$.ajax)。

这是一个传统的形式:

<form id="myFormId" action="/api/process/form" method="post">
    <!-- form fields here -->
    <button type="submit">SubmitAction</button>
</form>

如果将上述表单交给您(或者您创建它是因为它是语义 html),那么您可以将fetch代码包装在事件侦听器中,如下所示:

document.forms['myFormId'].addEventListener('submit', (event) => {
    event.preventDefault();
    // TODO do something here to show user that form is being submitted
    fetch(event.target.action, {
        method: 'POST',
        body: new URLSearchParams(new FormData(event.target)) // event.target is the form
    }).then((resp) => {
        return resp.json(); // or resp.text() or whatever the server sends
    }).then((body) => {
        // TODO handle body
    }).catch((error) => {
        // TODO handle error
    });
});

(或者,如果像原始海报一样,您想在没有提交事件的情况下手动调用它,只需将fetch代码放在那里并传递对form元素的引用,而不是使用event.target。)

文档:

获取:https : //developer.mozilla.org/en-US/docs/Web/API/Fetch_API

其他:https : //developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript 2018年那个页面没有提到fetch(还)。但它提到不推荐使用 target="myIFrame" 技巧。它还有一个用于“提交”事件的 form.addEventListener 示例。

来自 MDN 的重要说明:“即使响应是 HTTP 404 或 500,从 fetch() 返回的 Promise也不会拒绝 HTTP 错误状态。相反,它将正常解析(将 ok 状态设置为 false),并且它将仅在网络故障或任何阻止请求完成时拒绝。” 这意味着then回调必须检查 HTTP 状态。
2021-04-12 01:49:58

我正在这样做并且它的工作原理。

$('#form').submit(function(){
    $.ajax({
      url: $('#form').attr('action'),
      type: 'POST',
      data : $('#form').serialize(),
      success: function(){
        console.log('form submitted.');
      }
    });
    return false;
});
好吧,是的,根据需要返回 false 或 preventDefault 或 stopPropogation。
2021-03-22 01:49:58
您可能想要event.preventDefault();( event= 提交函数的第一个参数) 而不是return false. 返回 false 不仅会阻止浏览器提交表单,还会阻止其他可能很重要的副作用的发生。目前很多问题,相关这一点。
2021-03-23 01:49:58
为了更通用,您可以使用event.target.actionand$(event.target).serialize()代替$('#form').attr('action')and $('#form').serialize()
2021-03-26 01:49:58
FormData($("myform")[0])如果您尝试输入类型=文件上传,则可能需要使用
2021-04-01 01:49:58