0

我需要使用带有 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 提交表单。

谢谢

4

4 回答 4

4

您的代码不起作用有几个原因。请允许我将其分解并一一讨论问题。我将从最后一个(但最大的)问题开始:

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说法也有点奇怪:the readystate must be 4, and status == 200, not or。所以:

    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创建一个新的函数对象并将其分配给. 您可以编写此代码,以便您只需要创建 1 个函数。我现在不会进入我心爱的闭包(我认为你的盘子已经足够了),但重要的是要知道函数是对象,并且具有属性,就像其他所有东西一样:替换:onreadystatexmlRequest

    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 总是相同的,你可以,但是(但是闭包会更好,那么)。

好的,我就这样吧

于 2012-09-11T09:23:54.147 回答
0

这段代码可以让你理解。函数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!");
    }
}
于 2012-09-11T09:16:25.657 回答
0

看看这个页面。在这一行中:req.send(postData);发布数据是一个数组,其中包含应该发布到服务器的值。你有 null 那里。所以什么都没有发布。您只需调用请求并且不发送任何数据。在您的情况下,您必须从表单中收集所有值,因为 XMLHTTPRequest 不是可以简单地提交表单的东西。您必须使用 JS 传递所有值:

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

像 $_POST['value'] (在value1PHP 中)这样的服务器上的可用位置

URL 或您的呼叫方式也可能存在问题persistPage。persistPage 代码对我来说看起来不错,但也许我遗漏了一些东西。如果您在控制台中没有错误,您也可以查看一下。在任何浏览器中按 F12 并找到控制台选项卡。在 FF 中你可能需要安装 Firebug 扩展。此外,您将拥有包含所有请求的网络选项卡。打开 Firebug/Web Inspector(Chrome)/Developer Toolbar(IE) 并在调用 persistPage 后检查是否在其网络选项卡中注册了新请求。

于 2012-09-11T09:22:14.260 回答
0

我发现你调用了

xmlRequest.open()

方法两次,一次将 async 参数设置为 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;

希望这可以帮助。

于 2012-09-11T09:52:23.877 回答