[英]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¶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
語句是有點不可思議,太:在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
將創建一個新的函數對象,並將其分配給xmlRequest
的onreadystate
事件。 您可以編寫此代碼,以便只需要創建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.