使用 AJAX 响应提交数据和修改文档

Submit data and modify doc with AJAX response

我知道我可以使用 jQuery 执行以下操作,但目前我不想碰它。所以这里...

我有一个 PHP 文件,它生成一个 XML 文档,其中包含 table 的所有数据,如果没有 get 的话:

<?php
header ( 'Content-Type: text/xml; charset=utf-8' );
$con = @mysql_connect ( "localhost", "root", "" ) or die ( "Couldn't connect to database" );
mysql_select_db ( "dw00154727" );

if ($_GET) {
    $ingredient = $_GET ["name"];
    $query = "INSERT INTO ingredient VALUES('$ingredient')";
    mysql_query ( $query, $con );

    $query = "SELECT * FROM ingredient WHERE name='$ingredient'";
    $result = mysql_query ( $query, $con );
    $num_results = mysql_num_rows ( $result );
} else {
    $query = "SELECT * FROM ingredient";
    $result = mysql_query ( $query, $con );
    $num_results = mysql_num_rows ( $result );
}

$doc = new DOMDocument ();
$doc->formatOutput = true;
$root = $doc->createElement ( "ingredients" );

for($i = 0; $i < $num_results; $i ++) {
    $row = mysql_fetch_array ( $result );
    $node = $doc->createElement ( "ingredient" );

    $name = $doc->createElement ( "name" );
    $name->appendChild ( $doc->createTextNode ( $row ["name"] ) );

    $node->appendChild ( $name );
    $root->appendChild ( $node );
}
$doc->appendChild ( $root );
mysql_close ( $con );
echo $doc->saveXML (); // parse the XML
?>

要向它提交数据并使用 JS 修改文档,我这样做了:

<script type="text/javascript">
    function submit() {
        if (window.XMLHttpRequest) {
            xmlhttp = new XMLHttpRequest();
        } else {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        var ingredient = "ingredient_xml.php?ingredient="
                + document.getElementsByName("name").value;

        xmlhttp.open("GET", ingredient, false);
        xmlhttp.send();

        var x = xmlhttp.responseXML.getElementByTagName("ingredient");
        name = x[0].getElementByTagName("name")[0].childNodes[0].nodeValue;

        var row = document.createElement("tr");
        var tdname = document.createElement("td");

        tdname.appendChild(document.createTextNode(name));
        row.appendChild(tdname);

        document.getElementsByName("ingredients").appendChild(row);
    }
</script>
<form>
    <input type="text" name="name" />
    <input type='submit' value="Add" onclick="submit();" />
</form>

这将页面从 ingredient/ 重定向到 ingredient/?name=Malt,其中 Malt 是单击提交时文本框的内容。

接下来,我使用来自 MDN 的 FormData 示例修改了表单和函数:

<script type="text/javascript">
    function submit(form) {
        if (window.XMLHttpRequest) {
            xmlhttp = new XMLHttpRequest();
        } else {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }

        xmlhttp.open("post", form.action, true);
        xmlhttp.send(new FormData(form));

        var x = xmlhttp.responseXML.getElementByTagName("ingredient");
        name = x[0].getElementByTagName("name")[0].childNodes[0].nodeValue;

        var row = document.createElement("tr");
        var tdname = document.createElement("td");

        tdname.appendChild(document.createTextNode(name));
        row.appendChild(tdname);

        document.getElementsByName("ingredients").appendChild(row);
    }
</script>
<form action='ingredient_xml.php' onsubmit='submit(this); return false;'>
    <input type="text" name="name" />
    <input type='submit' value="Add" />
</form>

这次它将页面重定向到 ingredient/ingredient_xml.php?name=Malt。我做错了什么?

单击 "Add" 时会调用 submit(this),因此永远不会调用 return false;。您需要从函数 return false 并从 onsubmit:

调用 return

function otherSubmit(form) {
    /* ............ */
    alert('form submited');
    return false;
}
<form action='ingredient_xml.php' onsubmit='return otherSubmit(this);'>
    <input type="text" name="name" />
    <input type='submit' value="Add" />
</form>

JSFiddle Example

编辑:更改为 submit 以外的其他内容,例如 otherSubmit()

编辑 2:

你真的应该阅读更多关于 XMLHttp 和包装函数的内容,像这样:

var xmlhttp, table, xmlDoc;
function addIngredient(form) {  // XMLHttp function
    if (window.XMLHttpRequest) {
        xmlhttp = new XMLHttpRequest();
    } else {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }

    xmlhttp.open("post", form.action, true);
    xmlhttp.onreadystatechange = OnStateChange; // use OnStateChange function to get response
    xmlhttp.send(new FormData(form)); // send form

    return false;
}
function OnStateChange(){ // from onreadystatechange check if readyState is 4 or 0
    if (xmlhttp.readyState == 0 || xmlhttp.readyState == 4) {
        parseXMLResult(xmlhttp.responseXML); // send result to parse function
    }
}

function parseXMLResult(xmlDoc){ // parse your results
    table = document.getElementsByName("ingredients");

    // if table exists, clear contents
    if(table.length > 0){
        while (table[0].firstChild) {
            table[0].removeChild(table[0].firstChild);
        }
        table = table[0];
    // if table doesn't exist, create it
    } else {
        table = document.createElement("table");
        table.setAttribute('name', 'ingredients');
    }

    // create table head
    var row = document.createElement('tr');
    var thname = document.createElement('td');
    thname.appendChild(document.createTextNode('Name'));
    row.appendChild(thname);
    table.appendChild(row);

    // append results from XMLHttp response
    var x = xmlDoc.getElementsByTagName("ingredient");
    for (i = 0; i < x.length; i++) {
        name = x[i].getElementsByTagName("name")[0].childNodes[0].nodeValue;

        row = document.createElement("tr");
        var tdname = document.createElement("td");

        tdname.appendChild(document.createTextNode(name));
        row.appendChild(tdname);
        table.appendChild(row);
    }
    document.body.appendChild(table);

}

您可以在此处查看我的示例:HTML and PHP 针对您的问题进行定制。

您需要使用 onreadystatechange 检查 POST 状态并获取响应。

最佳做法是清除 table 并使用数据库中已有的内容重新创建。