コードが機能しない理由はいくつかあります。それを分解して、問題を 1 つずつ見ていきましょう。最後の (しかし最大の) 問題から始めます。
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
2 つのヘッダーのうち最初のヘッダーは常に必要というわけではありませんが、申し訳ありませんが、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-object を作成する 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
は新しい関数オブジェクトを作成し、それを のonreadystate
イベントに割り当てますxmlRequest
。このコードを記述して、関数を 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 が常に同じになる場合は、そうすることができます (ただし、クロージャーはさらに優れています)。
わかりました、そのままにしておきます