您的代码不起作用有几个原因。请允许我将其分解并一一讨论问题。我将从最后一个(但最大的)问题开始:
xmlRequest.send(null);
我的猜测是,您的代码基于一个GET
示例,其中 send 方法被调用null
,甚至undefined
作为参数 ( xhr.send()
)。这是因为 url 包含 GET 请求 ( .php?param1=val1¶m2=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 个函数。我现在不会进入我心爱的闭包(我认为你的盘子已经足够了),但重要的是要知道函数是对象,并且具有属性,就像其他所有东西一样:替换:onreadystate
xmlRequest
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 总是相同的,你可以,但是(但是闭包会更好,那么)。
好的,我就这样吧