簡體   English   中英

使用Ajax提交表單

[英]Form submit using Ajax

我需要使用帶有POST方法的Ajax提交表單。代碼如下,

function persistPage(divID,url,method){ 
    var scriptId = "inlineScript_" + divID;
    var xmlRequest = getXMLHttpRequest();   
    xmlRequest.open("POST",url,true);
    xmlRequest.onreadystatechange = function(){
    alert(xmlRequest.readyState + " :" + xmlRequest.status);
    if (xmlRequest.readyState ==4 || xmlRequest.status == 200)
          document.getElementById(divID).innerHTML=xmlRequest.responseText;
    };
    xmlRequest.open("POST", url, false);
    alert(xmlRequest.readyState);
    xmlRequest.send(null);
}

但表單未提交(請求未執行或未發布數據)。如何使用Ajax提交表單。

謝謝

有一些原因導致您的代碼無法正常工作。 請允許我分解並逐一討論這些問題。 我將從最后一個(但最大)的問題開始:

xmlRequest.send(null);

我的猜測是,您的代碼基於GET示例,其中send方法使用null調用,甚至undefined為參數( xhr.send() )。 這是因為url包含GET請求中的數據( .php?param1=val1&param2=val2... )。 使用post時,您將不得不將數據傳遞給send方法。

但是,讓我們不要超越自己:

function persistPage(divID,url,method)
{   
    var scriptId = "inlineScript_" + divID;
    var xmlRequest = getXMLHttpRequest();//be advised, older IE's don't support this
    xmlRequest.open("POST",url,true);
    //Set additional headers:
    xmlRequest.setRequestHeader('X-Requested-With', 'XMLHttpRequest');//marks ajax request
    xmlRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencode');//sending form

這兩個標頭中的第一個並不一定總是必需的,但是與對不起,IMO相比,保持安全更好。 現在開始:

    xmlRequest.onreadystatechange = function()
    {
        alert(xmlRequest.readyState + " :" + xmlRequest.status);
        if (xmlRequest.readyState ==4 || xmlRequest.status == 200)
            document.getElementById(divID).innerHTML=xmlRequest.responseText;
    };

這段代碼有很多問題。 您正在為對象分配方法,因此無需使用xmlRequest來引用您的對象,盡管從技術上講在這里有效,但是一旦將回調函數移到persistPage函數之外,這就會中斷。 xmlRequest變量是函數作用域的局部變量,不能在函數范圍之外訪問。 此外,正如我之前說的,這是一種方法: this直接指向對象
if語句是有點不可思議,太:在readystate 必須是4, 狀態== 200,而不是或。 所以:

    xmlRequest.onreadystatechange = function()
    {
        alert(this.readyState + " :" + this.status);
        if (this.readyState === 4 && this.status === 200)
        {
            document.getElementById(divID).innerHTML=this.responseText;
        }
    };
    xmlRequest.open("POST", url, false);
    alert(xmlRequest.readyState);//pointless --> ajax is async, so it will alert 0, I think
    xmlRequest.send(data);//<-- data goes here
}

如何填充數據取決於您,但是請確保格式與標題匹配:在這種情況下為'content type','x-www-form-urlencode' 這是一個這樣的請求的完整示例 ,因為我當時正在拋棄jQ轉向使用純JS,但這並不是一個真正的挑戰者,但是它是有用的,您可能會選擇一兩個東西。 特別是仔細研究function ajax()定義。 在其中,您將看到創建Xhr對象的X瀏覽器方法,並且那里也有一個函數可以對表格進行字符串化


無重點更新:

為了完整起見,我將添加一個完整的示例:

function getXhr()
{
    try
    {
        return XMLHttpRequest();
    }
    catch (error)
    {
        try
        {
            return new ActiveXObject('Msxml2.XMLHTTP');
        }
        catch(error)
        {
            try
            {
                return new ActiveXObject('Microsoft.XMLHTTP');
            }
            catch(error)
            {
                //throw new Error('no Ajax support?');
                            alert('You have a hopelessly outdated browser');
                            location.href = 'http://www.mozilla.org/en-US/firefox/';
            }
        }
    }
}
function formalizeObject(form)
{//we'll use this to create our send-data
    recursion = recursion || false;
    if (typeof form !== 'object')
    {
        throw new Error('no object provided');
    }
    var ret = '';
    form = form.elements || form;//double check for elements node-list
    for (var i=0;i<form.length;i++)
    {
        if (form[i].type === 'checkbox' || form[i].type === 'radio')
        {
            if (form[i].checked)
            {
                ret += (ret.length ? '&' : '') + form[i].name + '=' + form[i].value;
            }
            continue;
        }
        ret += (ret.length ? '&' : '') + form[i].name +'='+ form[i].value; 
    }
    return encodeURI(ret);
}

function persistPage(divID,url,method)
{   
    var scriptId = "inlineScript_" + divID;
    var xmlRequest = getXhr();
    xmlRequest.open("POST",url,true);
    xmlRequest.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    xmlRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencode');
    xmlRequest.onreadystatechange = function()
    {
        alert(this.readyState + " :" + this.status);
        if (this.readyState === 4 && this.status === 200)
        {
            document.getElementById(divID).innerHTML=this.responseText;
        }
    };
    xmlRequest.open("POST", url, false);
    alert(xmlRequest.readyState);
    xmlRequest.send(formalizeObject(document.getElementById('formId').elements));
}

只是為了好玩:此代碼未經測試,但應該可以正常工作。 但是,在每個請求上, persistPage將創建一個新的函數對象,並將其分配給xmlRequestonreadystate事件。 您可以編寫此代碼,以便只需要創建1個函數。 我現在不打算介紹我鍾愛的閉包(我想您已經對此有所了解),但是重要的是要知道函數是對象,並且具有屬性,就像其他所有事物一樣:
更換:

    xmlRequest.onreadystatechange = function()
    {
        alert(this.readyState + " :" + this.status);
        if (this.readyState === 4 && this.status === 200)
        {
            document.getElementById(divID).innerHTML=this.responseText;
        }
    };

有了這個:

//inside persistPage function:
xmlRequest.onreadystatechange = formSubmitSuccess;
formSubmitSuccess.divID = divID;//<== assign property to function
//global scope
function formSubmitSuccess()
{
    if (this.readyState === 4 && this.status === 200)
    {
        console.log(this.responseText);
        document.getElementById(formSubmitSuccess.divID).innerHTML = this.responseText;
        //^^ uses property, set in persistPAge function
    }
}

不過請不要使用它,因為在重新分配屬性時異步調用仍可能在運行,從而導致混亂。 但是,如果id總是相同,則可以(但是閉包會更好)。

好吧,我留在那兒

這段代碼可以讓您理解。 函數sendRequest將發送請求,並通過GetXMLHttpRequest功能打造xmlRequest

function SendRequest() {
    var xmlRequest = GetXMLHttpRequest(),
    if(xmlRequest) {

        xmlRequest.open("POST", '/urlToPost', true)

        xmlRequest.setRequestHeader("connection", "close");
        xmlRequest.onreadystatechange = function() {
            if (xmlRequest.status == 200) {
                // Success          
            }
            else {
                // Some errors occured                  
            }               
        };

        xmlRequest.send(null);
    }
}

function GetXMLHttpRequest() {
    if (navigator.userAgent.indexOf("MSIE") != (-1)) {
        var theClass = "Msxml2.XMLHTTP";
            if (navigator.appVersion.indexOf("MSIE 5.5") != (-1)) {
            theClass = "Microsoft.XMLHTTP";
        }
        try {
            objectXMLHTTP = new ActivexObject(theClass);
            return objectXMLHTTP;
        }
        catch (e) {
            alert("Errore: the Activex will not be executed!");
        }
    }
    else if (navigator.userAgent.indexOf("Mozilla") != (-1)) {
        objectXMLHTTP = new XMLHttpRequest();
        return objectXMLHTTP;
    }
    else {
        alert("!Browser not supported!");
    }
}

看一下這個頁面。 在這一行: req.send(postData); post data是一個數組,其值應發布到服務器。 您那里沒有空。 所以什么都沒有張貼。 您只調用請求,不發送任何數據。 對於您而言,您必須從表單中收集所有值,因為XMLHTTPRequest不能簡單地提交表單。 您必須使用JS傳遞所有值:

   var postData = {};
   postData.value1 = document.getElementById("value1id").value;
   ...
   xmlRequest.send(postData);

像$ _POST ['value']這樣的服務器上可以使用value1地方(在PHP中)

URL或您如何調用persistPage也可能有問題。 persistPage代碼對我來說似乎還不錯,但也許我缺少了一些東西。 如果您在控制台中沒有錯誤,也可以看看。 在任何瀏覽器中按F12鍵,然后找到控制台選項卡。 在FF中,您可能需要安裝Firebug擴展。 此外,您還將在“網絡”標簽中看到所有請求。 調用persistPage之后,打開Firebug / Web檢查器(Chrome)/開發人員工具欄(IE)並檢查是否在其網絡選項卡中注冊了新請求。

我發現您已經調用了

xmlRequest.open()

方法兩次,一個異步參數為true,另一個為false。 您打算做什么?

xmlRequest.open("POST", url, true);
...
xmlRequest.open("POST", url, false);

如果要發送異步請求,請將參數傳遞為true。 另外,要使用“ POST”方法,您最好按照Elias的建議發送請求標頭,

xmlRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencode');

否則,您仍然可能會遇到意外問題。

如果要同步請求,實際上,您可以在發送請求后立即處理響應,就像:

xmlRequest.open("POST", url, false);
xmlRequest.send(postData);
// handle response here
document.getElementById(scriptId).innerHTML = xmlRequest.responseText;

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM