使用ajax提交表单

35

我正在开发一个应用程序(类似于我大学的社交网络)。我需要添加一个评论(在特定数据库中插入一行)。为此,我在我的html页面上有一个HTML表单,其中包含各种字段。在提交时,我不使用表单的动作,而是使用自定义javascript函数来处理提交前的一些数据。

function sendMyComment() {

    var oForm = document.forms['addComment'];
    var input_video_id = document.createElement("input");
    var input_video_time = document.createElement("input");

    input_video_id.setAttribute("type", "hidden");
    input_video_id.setAttribute("name", "video_id");
    input_video_id.setAttribute("id", "video_id");
    input_video_id.setAttribute("value", document.getElementById('video_id').innerHTML);

    input_video_time.setAttribute("type", "hidden");
    input_video_time.setAttribute("name", "video_time");
    input_video_time.setAttribute("id", "video_time");
    input_video_time.setAttribute("value", document.getElementById('time').innerHTML);

    oForm.appendChild(input_video_id);
    oForm.appendChild(input_video_time);

    document.forms['addComment'].submit();
}

最后一行将表单提交到正确的页面。它运行良好。但是我希望使用ajax提交表单,因为我不知道如何获取表单输入值。有人能帮助我吗?


你有进行过搜索吗?请查看以下链接:https://dev59.com/GXE85IYBdhLWcg3w9odJ 和 https://dev59.com/TXI-5IYBdhLWcg3wO1rl。 - mohsen dorparasti
8个回答

35

没有人给出一个纯粹的javascript答案(正如OP所请求的那样),因此在这里:

function postAsync(url2get, sendstr)    {
    var req;
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        }
    if (req != undefined) {
        // req.overrideMimeType("application/json"); // if request result is JSON
        try {
            req.open("POST", url2get, false); // 3rd param is whether "async"
            }
        catch(err) {
            alert("couldnt complete request. Is JS enabled for that domain?\\n\\n" + err.message);
            return false;
            }
        req.send(sendstr); // param string only used for POST

        if (req.readyState == 4) { // only if req is "loaded"
            if (req.status == 200)  // only if "OK"
                { return req.responseText ; }
            else    { return "XHR error: " + req.status +" "+req.statusText; }
            }
        }
    alert("req for getAsync is undefined");
}

var var_str = "var1=" + var1  + "&var2=" + var2;
var ret = postAsync(url, var_str) ;
    // hint: encodeURIComponent()

if (ret.match(/^XHR error/)) {
    console.log(ret);
    return;
    }

在您的情况下:

var var_str = "video_time=" + document.getElementById('video_time').value 
     + "&video_id=" + document.getElementById('video_id').value;

小问题 - 您将方法称为“postAsync”,但实际上它是同步工作的(请求的async属性设置为“false”)。 - Psychemaster
@Psychemaster,干得好。这段代码是我实际使用的代码修改而来的,在某个时候,我认为它可以作为函数的参数进行指定。我想我只是从未更改该函数名称的那一部分。 - insaner
1
我必须添加 req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 才能使其正常工作。 - sevko
@sevko,是的,这在很大程度上取决于您收到的数据。例如,如果您收到JSON格式的文本,则可能需要指定“application/json”。 - insaner

33

怎么样呢?

$.ajax({
  type: 'POST',
  url: $("form").attr("action"),
  data: $("form").serialize(), 
  //or your custom data either as object {foo: "bar", ...} or foo=bar&...
  success: function(response) { ... },
});

1
为什么我们需要进行序列化? - Павел Кушнеревич
1
在这种情况下,您可能需要序列化,以便在与后端代码通信时值可以保持其类型(尽管我相信它们是非常通用的类型)。如果您在后端使用JS,则这可能非常有帮助(我通常使用Python或其他语言,但发现这可以有所帮助)。 - Harlin

27

你可以使用 FormData 捕获表单输入值,并通过 fetch 发送它们

fetch(form.action,{method:'post', body: new FormData(form)});

function send(e,form) {
  fetch(form.action,{method:'post', body: new FormData(form)});

  console.log('We send post asynchronously (AJAX)');
  e.preventDefault();
}
<form method="POST" action="myapi/send" onsubmit="send(event,this)">
    <input hidden name="crsfToken" value="a1e24s1">
    <input name="email" value="a@b.com">
    <input name="phone" value="123-456-789">
    <input type="submit">    
</form>

Look on chrome console>network before 'submit'


12

你可以为提交按钮添加一个onclick函数,但是按回车键无法触发该函数。就我而言,我使用以下代码:

<form action="" method="post" onsubmit="your_ajax_function(); return false;">
    Your Name <br/>
    <input type="text" name="name" id="name" />
    <br/>
    <input type="submit" id="submit" value="Submit" />
</form>

希望这有所帮助。


10

这里是一个通用解决方案,它遍历表单中的每个字段并自动创建请求字符串。它使用新的 fetch API。自动读取表单属性:methodaction 并获取表单内的所有字段。支持一维数组字段,例如 emails[]。可以作为一个通用解决方案,轻松管理许多(也许是动态的)表单,并拥有单一的真相来源 - html。

document.querySelector('.ajax-form').addEventListener('submit', function(e) {
    e.preventDefault();
    let formData = new FormData(this);
    let parsedData = {};
    for(let name of formData) {
      if (typeof(parsedData[name[0]]) == "undefined") {
        let tempdata = formData.getAll(name[0]);
        if (tempdata.length > 1) {
          parsedData[name[0]] = tempdata;
        } else {
          parsedData[name[0]] = tempdata[0];
        }
      }
    }

    let options = {};
    switch (this.method.toLowerCase()) {
      case 'post':
        options.body = JSON.stringify(parsedData);
      case 'get':
        options.method = this.method;
        options.headers = {'Content-Type': 'application/json'};
      break;
    }

    fetch(this.action, options).then(r => r.json()).then(data => {
      console.log(data);
    });
});

<form method="POST" action="some/url">
    <input name="emails[]">
    <input name="emails[]">
    <input name="emails[]">
    <input name="name">
    <input name="phone">
</form>

4

使用 jQuery 更加容易,因为这只是一项针对大学任务的练习,您不需要保存代码。

因此,您的代码将如下所示:

function sendMyComment() {
    $('#addComment').append('<input type="hidden" name="video_id" id="video_id" value="' + $('#video_id').text() + '"/><input type="hidden" name="video_time" id="video_time" value="' + $('#time').text() +'"/>');
    $.ajax({
        type: 'POST',
        url: $('#addComment').attr('action'),
        data: $('form').serialize(), 
        success: function(response) { ... },
    });

}

2
我建议您在这种情况下使用jQuery。试试看吧。
<div id="commentList"></div>
<div id="addCommentContainer">
    <p>Add a Comment</p> <br/> <br/>
    <form id="addCommentForm" method="post" action="">
        <div>
            Your Name <br/>
            <input type="text" name="name" id="name" />


            <br/> <br/>
            Comment Body <br/>
            <textarea name="body" id="body" cols="20" rows="5"></textarea>

            <input type="submit" id="submit" value="Submit" />
        </div>
    </form>
</div>​

$(document).ready(function(){
    /* The following code is executed once the DOM is loaded */

    /* This flag will prevent multiple comment submits: */
    var working = false;
    $("#submit").click(function(){
    $.ajax({
         type: 'POST',
         url: "mysubmitpage.php",
         data: $('#addCommentForm').serialize(), 
         success: function(response) {
            alert("Submitted comment"); 
             $("#commentList").append("Name:" + $("#name").val() + "<br/>comment:" + $("#body").val());
         },
        error: function() {
             //$("#commentList").append($("#name").val() + "<br/>" + $("#body").val());
            alert("There was an error submitting comment");
        }
     });
});
});​

4
很棒的功能,但是仅靠var working = false本身并没有作用。我猜想你打算在条件语句中使用它来防止多次提交。 - Goose

2
我想添加一种新的纯 javascript 方法来实现这个功能,我认为这种方法更加简洁,它使用了 fetch() API。这是一种现代的网络请求实现方式。在您的情况下,由于您已经有了一个 表单元素,我们可以直接使用它来构建我们的请求。
const formInputs = oForm.getElementsByTagName("input");
let formData = new FormData();
for (let input of formInputs) {
    formData.append(input.name, input.value);
}

fetch(oForm.action,
    {
        method: oForm.method,
        body: formData
    })
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.log(error.message))
    .finally(() => console.log("Done"));

正如您所看到的,使用它比XMLHttpRequest更简洁。


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