提交表单而不重新加载页面

119
我有一个分类广告网站,在展示广告的页面上,我正在创建一个“给朋友发送提示”的表单...
所以任何想要的人都可以将广告的提示发送给一些朋友的电子邮件地址。
我猜这个表单必须提交到一个php页面,对吗?
<form name="tip" method="post" action="tip.php">
  Tip somebody: 
  <input 
    name="tip_email"
    type="text" 
    size="30" 
    onfocus="tip_div(1);" 
    onblur="tip_div(2);"
  />
  <input type="submit" value="Skicka Tips" />
  <input type="hidden" name="ad_id" />
</form>

当提交表单时,页面会重新加载...我不想要那样...
有没有办法让它不重新加载但仍然发送邮件? 最好不要使用ajax或jquery...

13
要发送表单,您必须发出HTTP请求。而不加载页面进行HTTP请求就是Ajax的含义。这就像试图在没有车辆的情况下驾车去城镇一样困难。 - Quentin
12
“不用 ajax 或者 jquery”听起来就像是“我想要一辆没有轮子的车”。 - Your Common Sense
13
@Keith,几乎可以使用<iframe>target属性来实现。 - alex
16
我看了标题,想到“啊,他只需要Ajax”。当我一边啜着咖啡一边继续阅读问题并在脑海中准备回答时,问题结束时我的咖啡洒满了屏幕... - BalusC
使用以下jQuery插件来实现此功能:https://github.com/jinujd/jQuery-Async-Form - Jinu Joseph Daniel
显示剩余5条评论
19个回答

114

我发现了一种更容易的方法。如果您在页面中放置一个Iframe,则可以将操作的退出重定向到那里并使其显示出来。当然,您也可以什么都不做。在这种情况下,您可以将Iframe的显示设置为none。

<iframe name="votar" style="display:none;"></iframe>
<form action="tip.php" method="post" target="votar">
    <input type="submit" value="Skicka Tips">
    <input type="hidden" name="ad_id" value="2">            
</form>

3
我使用了action="about:blank" - ThorSummoner
4
可以,您仍然可以获取诸如$_POST["ad_id"]之类的值。 - William
很遗憾,这个解决方案对我不起作用,因为提交表单会导致JavaScript再次运行并调用文档准备事件。 - bgh
1
这看起来是一个非常好的答案。但是使用这种方法,处理不同的错误代码和验证错误将是不可能的。但是对于为某人创建一些示例代码,这可能会很方便。 - He Nrik

83
编辑说明:这个答案在历史上被接受为正确答案,但现在已经过时。虽然代码仍然有效,但如果您的目标浏览器支持FormDataFetch API(即几乎所有现代浏览器),请考虑查看this answer

您需要提交一个AJAX请求来发送电子邮件,而不重新加载页面。请参考http://api.jquery.com/jQuery.ajax/

您的代码应该类似于:

$('#submit').click(function() {
    $.ajax({
        url: 'send_email.php',
        type: 'POST',
        data: {
            email: 'email@example.com',
            message: 'hello world!'
        },
        success: function(msg) {
            alert('Email Sent');
        }               
    });
});

表单将在后台提交到send_email.php页面,该页面需要处理请求并发送电子邮件。

4
如果您包括HTML,它会是什么样子? - blueprintchris
6
send_email.php 应该改为 "send_email.php"。 - Bear
3
你如何只使用纯JavaScript中的基本AJAX实现这个? - Adam
3
如果表单仍在刷新,请在最后一个闭括号之前添加 return false; - The Codesee
1
这个答案需要依赖jQuery。在2020年的现代解决方案中,可以使用XMLHttpRequest,如此答案所述。 - user2225804
显示剩余4条评论

24

最快、最简单的方法是使用 iframe。 在您的页面底部放置一个框架。

<iframe name="frame"></iframe>

在您的表单中,进行如下操作。

<form target="frame">
</form>

并且在你的 CSS 中使框架不可见。

iframe{
  display: none;
}

6
应该使用"display:none;"而不是"border:0px;"。我尝试进行编辑,但是我的编辑被审核人员拒绝了,他们似乎没有查看编辑注释。请修改你的答案以修复这段代码。 - AStopher
2
我建议通过id或class来调用css。 - RaRdEvA
1
这真是救命稻草。我有一个高度详细的表单,有超过50个输入字段,我很害怕在开发模式下每次都要重新填写它。现在我不必如此了。非常推荐这个解决方案用于开发目的。 - Matthew Wolman

21

你可以使用AJAX,或者:

  • 创建并将一个iframe添加到文档中
  • 将iframe的名称设置为“foo”
  • 将表单的目标设置为“foo”
  • 提交表单
  • 让表单的操作使用“parent.notify(...)”来呈现JavaScript以给出反馈信息
  • 可选地,您可以删除iframe

5
仍然是Ajax,不是XHR,但仍然是Ajax。 - Quentin
3
太妙了,谢谢。以下是需要翻译的内容:"great trick thank you. sample for usage <form id="myGiswebForm" method="post" action="https://******/saveForm.asp" target="myiframe"> and <iframe style="display:none;" src="" name="myiframe"></iframe>" 非常巧妙,谢谢。以下是使用示例:<form id="myGiswebForm" method="post" action="https://******/saveForm.asp" target="myiframe"><iframe style="display:none;" src="" name="myiframe"></iframe> - aiternal

17

在不刷新页面的情况下提交表单并在同一页上获取提交数据的结果。

1.) IFRAME

当表单被提交时,将执行action并定位到特定的iframe以重新加载。

index.php

<iframe name="content" style="">
</iframe>
<form action="iframe_content.php" method="post" target="content">
<input type="text" name="Name" value="">
<input type="submit" name="Submit" value="Submit">
</form>

iframe_content.php

<?php
$Submit = isset($_POST['Submit']) ? $_POST['Submit'] : false;
$Name = isset($_POST['Name']) ? $_POST['Name'] : '';
if($Submit){
 echo $Name;
}
?>

2.) AJAX

Index.php:

<form >
    <input type="" name="name" id="name">
    <input type="" name="descr" id="descr">
    <input type="submit" name="" value="submit" onclick="return clickButton();">
</form>
<p id="msg"></p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript">
function clickButton(){
    var name=document.getElementById('name').value;
    var descr=document.getElementById('descr').value;
    $.ajax({
        type:"post",
        url:"server_action.php",
        data: 
        {  
           'name' :name,
           'descr' :descr
        },
        cache:false,
        success: function (html) 
        {
           alert('Data Send');
           $('#msg').html(html);
        }
    });
    return false;
 }
</script>

server_action.php

<?php 
$name = isset($_POST['name']) ? $_POST['name'] : '';
$descr = isset($_POST['descr']) ? $_POST['descr'] : '';


echo $name;
echo $descr;

?>

标签:


我在互联网上搜索了很多次。 我之前使用过Jquery,但是它有时候工作,有时候不工作, 所以我认为你回答中提到的ajax是最好的选择。 - Sorry IwontTell

9

不需要使用XHR或jQuery的现代答案

已经是2022年了,当我们拥有Fetch APIFormData API时,我们不需要使用旧工具如XHR或jQuery!

我们需要做的第一件事是使用event.preventDefault()阻止默认表单提交行为:

form.addEventListener("submit", function(event){
    event.preventDefault();
    // ...
});

现在我们需要用自己的AJAX请求替换提交行为。Fetch API让提交表单数据变得非常简单 - 只需创建一个新的FormData对象,将其填充为表单的值,并将其用作fetch请求的主体即可:
fetch(form.action, {
    method: "post",
    body: new FormData(form)
});

请注意,这将使用 multipart/form-data 编码类型提交 HTTP 请求。如果你需要使用 application/x-www-form-urlencoded 格式发布数据,请从 FormData 对象创建一个新的 URLSearchParams 对象,并将其用作 fetch 的主体。1
fetch(form.action, {
    method: "post",
    body: new URLSearchParams(new FormData(form))
});

最后,如果您想将HTTP请求提交为JSON,请使用以下内容:2

fetch(form.action, {
    method: "post",
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify(Object.fromEntries(new FormData(form)))
});

这是一个完整的代码示例:

let form = document.querySelector("form");

form.addEventListener("submit", function(event){
    event.preventDefault();
  
    fetch(form.action, {
        method: "post",
        body: new URLSearchParams(new FormData(form)) // for application/x-www-form-urlencoded
        // body: new FormData(form) // for multipart/form-data
    });
});
<form method="POST">
  <input name="name" placeholder="Name" />
  <input name="phone" type="tel" placeholder="Phone" />
  <input name="email" type="email" placeholder="Email" />
  <input name="submit" type="submit" />
</form>


1 这两种编码类型有什么区别?

2 代码基于这个回答中的"How to convert FormData (HTML5 object) to JSON"。请注意,如果键重复,则只使用最后一个值。


完美解决了!非常有用的现代技巧,特别是使用 new URLSearchParams(),它需要与正常提交相同的行为,但显然不太明显。 - Nik
顺便说一下,@SuperStomer,你可能应该在第一个fetch()代码段中删除new URLSearchParams(...),因为它与下面的重复了。另外,还有另一种不错的方法,可以指定内容类型为“JSON”,以便进行方便和高效的通用数据交换:fetch("/api/func", { method: "POST", headers: { "Content-Type":"application/json" }, body: JSON.stringify({a:1,b:2}) }); - Nik
@Nik 抱歉,我不小心复制粘贴了相同的代码两次。已修复。 - SuperStormer

7
另外一种可能性是直接使用JavaScript链接到您的函数:
<form action="javascript:your_function();" method="post">

...


2
简直不敢相信这么简单的解决方案居然奏效了,值得更多的点赞。 - Hashim Aziz

5

在这种情况下,必须借助jquery-ajax。没有ajax,目前没有解决方案。

首先,在提交表单时调用JavaScript函数。只需设置onsubmit="func()"。即使函数被调用,提交的默认操作仍将执行。如果执行了该操作,将无法阻止页面刷新或重定向。因此,下一步任务是防止默认操作。在func()的开头插入以下行。

event.preventDefault()

现在,不会有重定向或刷新。因此,您只需从func()发起ajax调用,并在调用结束时执行任何想要执行的操作。 示例: 表单:
<form id="form-id" onsubmit="func()">
    <input id="input-id" type="text">
</form>

Javascript:

function func(){
    event.preventDefault();
    var newValue = $('#input-field-id').val();
    $.ajax({
        type: 'POST',
        url: '...',
        data: {...},
        datatype: 'JSON',
        success: function(data){...},
        error: function(){...},
    });
}

4

这就是没有使用jQuery和AJAX的情况下,它可以正常工作,并且使用简单的iFrame非常出色。我很喜欢它,它在Opera10、FF3和IE6中都能正常工作。感谢上面一些帖子指引我正确的方向,这也是我发帖的唯一原因:

<select name="aAddToPage[65654]" 
onchange="
    if (bCanAddMore) {
        addToPage(65654,this);
    }
    else {
        alert('Could not add another, wait until previous is added.'); 
        this.options[0].selected = true;
    };
" />
<option value="">Add to page..</option>
[more options with values here]</select>

<script type="text/javascript">
function addToPage(iProduct, oSelect){
    iPage = oSelect.options[oSelect.selectedIndex].value;
    if (iPage != "") {
        bCanAddMore = false;
        window.hiddenFrame.document.formFrame.iProduct.value = iProduct;
        window.hiddenFrame.document.formFrame.iAddToPage.value = iPage;
        window.hiddenFrame.document.formFrame.submit();
    }
}
var bCanAddMore = true;</script> 

<iframe name="hiddenFrame" style="display:none;" src="frame.php?p=addProductToPage" onload="bCanAddMore = true;"></iframe>

上述被调用的页面生成的PHP代码:

if( $_GET['p'] == 'addProductToPage' ){  // hidden form processing
  if(!empty($_POST['iAddToPage'])) {
    //.. do something with it.. 
  }
  print('
    <html>
        <body>
            <form name="formFrame" id="formFrameId" style="display:none;" method="POST" action="frame.php?p=addProductToPage" >
                <input type="hidden" name="iProduct" value="" />
                <input type="hidden" name="iAddToPage" value="" />
            </form>
        </body>
    </html>
  ');
}

3
不要使用PHP的print函数输出HTML代码,而是在闭合PHP标签?>后添加HTML代码。避免不必要地使用exit函数(仅在出现致命错误等情况下使用)。 - Oriol
是的,谢谢你指出来。这只是一个必要的例子,我在我的系统中并没有这样做。 - Tyler
这个答案需要很多工作,但还有许多其他的。 - ReinstateMonica3167040
唯一的副问题是其中的get(),因为我不希望表单状态可被书签标记或缓存。 - drtechno

4

这应该可以解决你的问题。
在这段代码中,当提交按钮被点击后,我们调用jQuery Ajax并传递要发布的URL
类型为POST/GET
数据:数据信息,您可以选择输入字段或任何其他内容。
成功:如果一切正常从服务器返回回调函数
函数参数文本、HTML或JSON,来自服务器的响应
在成功时,您可以编写警告(如果您获得的数据处于某种状态)等。或执行下一步要做什么的代码。

<form id='tip'>
Tip somebody: <input name="tip_email" id="tip_email" type="text" size="30" onfocus="tip_div(1);" onblur="tip_div(2);"/>
 <input type="submit" id="submit" value="Skicka Tips"/>
 <input type="hidden" id="ad_id" name="ad_id" />
 </form>
<script>
$( "#tip" ).submit(function( e ) {
    e.preventDefault();
    $.ajax({
        url: tip.php,
        type:'POST',
        data:
        {
            tip_email: $('#tip_email').val(),
            ad_id: $('#ad_id').val()
        },
        success: function(msg)
        {

            alert('Email Sent');
        }               
    });
});
</script>

虽然这段代码片段可能解决了问题,但它并没有解释为什么或者如何回答这个问题。请在您的代码中包含一个解释,因为这真的有助于提高您的帖子质量。记住,您正在为未来的读者回答问题,而这些人可能不知道您的代码建议的原因。标记者/审核员:对于仅包含代码的答案,请进行投票,而不是删除! - Scott Weldon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接