顯示具有 Ajax 標籤的文章。 顯示所有文章
顯示具有 Ajax 標籤的文章。 顯示所有文章
2014-03-05 23:38

利用 HTTP Status Codes 傳遞 Ajax 成功失敗的狀態

一般處理 Ajax 回應時會傳送的資訊種類有:資料、成功訊息、錯誤訊息、失敗訊息以及處理狀態,傳遞的資訊種類並不一致,再加上除了資料之外,通常還希望能傳遞處理狀態,這種情況大部分會選擇是以 JSON 的方式傳遞這兩個訊息,以下是常見的幾種格式:

{ code: 1, msg: "OK" }
{ success: true, result: "data", errorMsg: "" }
{ status: 'success', result: [], errorMsg: "" }
//...

但以執行狀態跟操作行為作一個歸納,可以區分以下幾種回傳結果:
資料操作 HTTP Method 成功 錯誤/失敗
檢視(Read) GET 資料 錯誤/失敗訊息
新增(Create)
修改(Update)
刪除(Delete)
POST 成功訊息 錯誤/失敗訊息

從上面的歸納可以看出規律性,接著只要有方法可以傳送處理的狀態,以及能夠區分資料的種類,其實就單純很多,而 HTTP Status Codes 就是用來傳遞 HTTP 的處理狀態,如果利用這個方式來傳遞自訂的處理狀態,這樣 HTTP Content 就可以很單純傳遞資料,讓資料格式不受限於 JSON,還可以使用其他格式(text, xml, html),而且 XMLHttpRequest 本身就有處理 HTTP Status Codes 的能力,而 jQuery.ajax 也有提供 error status 的處理,所以可以利用這個來定義狀態的處理,在 HTTP Status Codes 有幾個已經定義狀態,很適合用來回傳處理狀態的資訊:

400 Bad Request 錯誤的請求 適用在表單內容的錯誤,如必填欄位未填、Email 格式錯誤
403 Forbidden 沒有權限,被禁止的 適用在沒有登入或權限不足
500 Internal Server Error 內部服務器錯誤 適用在程式的錯誤


jQuery 接收資訊的範例
$.ajax({
    type: "POST",
    url: document.location,
    success: function (data, textStatus, jqXHR) {
        alert(data);
    },
    error: function (jqXHR, textStatus, errorThrown) {
        alert(jqXHR.responseText);
    }
});


PHP 傳遞錯誤訊息的範例
if (php_sapi_name() == 'cgi'){
    header("Status: 400 Bad Request");
}else{
    header("HTTP/1.0 400 Bad Request");
}
exit("儲存失敗!!");


C# MVC 傳遞錯誤訊息的範例
Response.TrySkipIisCustomErrors = true;
Response.StatusCode = 400;
return Content("儲存失敗!!");
2009-05-29 02:52

Ajax(XMLHttpRequest) 同步與非同步(異步)連結

首先針對 Internet Explorer 的連結物件做統一的處理,將 ActiveXObject 包裝成與 Mozilla 中的 XMLHttpRequest 相同的物件,這樣我們就可以排除瀏覽器的問題。

/* 針對不同瀏覽器的前置處理宣告 */
if (typeof(XMLHttpRequest)=="undefined" && window.ActiveXObject) {
XMLHttpRequest=function(){
var arrSignatures = [
"MSXML2.XMLHTTP.5.0",
"MSXML2.XMLHTTP.4.0",
"MSXML2.XMLHTTP.3.0",
"MSXML2.XMLHTTP",
"Microsoft.XMLHTTP"];
for (var i = 0; i < arrSignatures.length; i++) {
try{
var oRequest = new ActiveXObject(arrSignatures[i]);
return oRequest;
}catch(oError){/*ignore*/}
}
throw new Error("MSXML is not installed on your system.");
};
}



我們可以直接用 XMLHttpRequest 去處理 Ajax 連結,這是以[GET]方式建立[非同步]的傳送連接,如果要使用 POST 做連結請參考之前的文章[Ajax 使用 POST 傳送]。
POST 的差別只在於 open,setRequestHeader,send 這三個地方的設定。

/**=( 以[GET]方式建立[非同步]傳送連接 )====================*/

// 產生要求資料的 URL 及 GET 參數
var sURL = "check_in.php?user=xxxx&pass=xxxx";

// 建立 XMLHttpRequest 物件,並且送要求
var oRequest = new XMLHttpRequest();

// 設定連結方式及位址,並以非同步方式處理
oRequest.open("GET", sURL, true);
/*
void open(
in AUTF8String method, 傳送的方式
in AUTF8String url, 要求的位址
[optional] in boolean async, 同步方式(預設 true 非同步)
[optional] in AString user, 使用者名稱(預設為空字串)
[optional] in AString password 使用者密碼(預設為空字串)
);
*/

// 建立接收狀態的事件處理
oRequest.onreadystatechange = function(){
/*
當狀態變更時都會呼叫此事件
可利用 readyState 取得目前的狀態
所有可能的傳送狀態值如下:
0 (還沒開始)
1 (讀取中)
2 (已讀取)
3 (資訊交換中)
4 (請求完成)
*/
switch(oRequest.readyState){
case 0: // 開始前的程式處理
break;
case 1: // 讀取中的程式處理
break;
case 2: // 已讀取的程式處理
break;
case 3: // 資訊交換中的程式處理
break;
case 4: // 請求完成的程式處理
/* (在此處加入開啟已停用選項的設置) */

/*可以從responseText或responseXML取得傳回的資料*/
// 處理傳回為 200 的 HTTP 狀態碼
if (oRequest.status == 200) {
// 接受資料成功


// 將 responseText 中的文字轉成 JSON 物件
json = eval('('+oRequest.responseText+')');

// 處理其他錯誤 HTTP 狀態碼
}else{
/*接收資料失敗,可以從 statusText 取得錯誤狀態資訊*/
alert(oRequest.statusText);
}
break;
}

}

/* (在此處可以加入一些網頁選項停用的設置,以防止重複送出) */

// 送出 Ajax 要求
oRequest.send(null);
/*
以POST傳送時,這裡可以輸入(XML,串流,字串,JSON格式)
以GET傳送時,這裡只要輸入 null 或是空的
*/

// 強制中斷
//oRequest.abort();
/* 此函數方法可用在必要時,強制終止非同步請求 */



建立[同步]的 Ajax 傳送連接只要將 onreadystatechange 裡的程序移到 send 後面就可以了,如果非必要,最好還是不要以[同步]方式做連結,再處理死結的時候會多一些必要的處理,除非保證連結是 100% 正常且可行的。

/**=( 以[GET]方式建立[同步]傳送連接 )====================*/

// 產生要求資料的 URL 及 GET 參數
var sURL = "check_in.php?user=xxxx&pass=xxxx";

// 建立 XMLHttpRequest 物件,並且送要求
var oRequest = new XMLHttpRequest();

// 設定連結方式及位址,並以同步方式處理
oRequest.open("GET", sURL, false);
/*
void open(
in AUTF8String method, 傳送的方式
in AUTF8String url, 要求的位址
[optional] in boolean async, 同步方式(預設 true 非同步)
[optional] in AString user, 使用者名稱(預設為空字串)
[optional] in AString password 使用者密碼(預設為空字串)
);
*/

/* 開始前的程式處理... */

/* 讀取中的程式處理... */

// 送出 Ajax 要求
oRequest.send(null);
/*
以POST傳送時,這裡可以輸入(XML,串流,字串,JSON格式)
以GET傳送時,這裡只要輸入 null 或是空的
*/

// 請求完成的程式處理
/*可以從responseText或responseXML取得傳回的資料*/
// 處理傳回為 200 的 HTTP 狀態碼
if (oRequest.status == 200) {
// 接受資料成功

// 將 responseText 中的文字轉成 JSON 物件
json = eval('('+oRequest.responseText+')');

// 處理其他錯誤 HTTP 狀態碼
}else{
/*接收資料失敗,可以從 statusText 取得錯誤狀態資訊*/
alert(oRequest.statusText);
}



參考來源:
XMLHttpRequest - MDC
XMLHttpRequest的同步请求和Firefox的问题_网银

爪哇豆的秘密:AJAX深度歷險1(Getting Started)
Ajax内部交流文档
MoztwWiki:AJAX 上手篇
維基百科:AJAX
語言技術:Ajax Gossip
2008-08-20 17:27

Ajax 模組架構的應用

Ajax 模組架構的應用
一樣的就之前所提到的問題(Ajax 開發所產生的問題),這是另一種以模組架構為基礎的方法,模組開發的好處我就不多作說明了,主要的行為模式是:
  1. 在請求 Page 時就先將 Module Include,讓頁面再第一次讀取時就可以完整呈現。
  2. 在頁面需要執行局部置換時,再利用 Ajax 向 Module 請求局部內容。

這樣做既不會失去模組開發的優點,也不會有 Ajax 造成的過長等待,讓 Ajax 主要應用在局部置換及 UI 處理。
2008-08-19 16:17

利用屏壁來延長頁面的呈現時間

就之前提到的問題(Ajax 開發所產生的問題),這很可能連帶出現以下問題:
  1. 瀏覽者再頁面尚未完整呈現時誤觸連結,造成錯誤操作。
  2. 功能的初始未完成,瀏覽者再使用上出現無法動作的錯愕情形。


這些問題可以用一個有效的方法去延長瀏覽者的等待時間,在一開始的頁面裡預設疊上一個遮蓋整個頁面的等待圖示,在 JavaScript 處理完後再移出屏壁,一個很好的範例就是 Gmail,再一個主要的頁面呈現前,置入一個等待圖示去避免一些可能的不當操作。

順帶一提,Gmail 利用 ifreme 去做出局部置換的效果,這樣做的好處是,瀏覽器會自動去紀錄上下頁,在 Ajax 的應用上瀏覽紀錄這件事是必須額外處理的。
2008-08-18 17:27

利用 Ajax 減少 Server 運算量

在 Ajax 還沒有出現時 JavaScript 本身就可以執行許多計算方面的程式了,像之前的文章『HTML 比較(diff)』、『數獨(sudoku)解題』、『線性代數-計算機』等都是利用 JavaScript 去達成的計算程式,象 Yahoo 也有在 Login 時利用 JavaScript 做 md5 的計算,其實瀏覽器還是可以做一些有規模的運算。

利用 Ajax 減少 Server 運算量

主要是將運算資料取回,計算結果明細後,再跟 Server 取得剩餘的詳細資料,這個架構可以讓 Server 原本的運算量轉由瀏覽器執行,是一個以空間換時間的作法,當然有一好沒兩好,沒錯這樣的方法明顯會發生之前所說的問題(Ajax 開發所產生的問題),是否要用這個方法就看各位的考量了。

其中特別要注意的一些事項:
  1. 再資訊必須是即時性,且運算量大於一定時間以上時,考慮這種架構才會有意義,要不然只會浪費頻寬。
  2. 資料安全性問題,必須定義哪些瀏覽者可以取得計算資料,要不然會造成嚴重的漏洞。
  3. 資料量的大小,太大的資料可能會造成瀏覽器整個當掉,再規劃時要特別注意最大上限,至於詳細的範圍要依瀏覽者的設備而定。
2008-08-14 16:17

Ajax 開發所產生的問題

wacanai 的開發中發現了一個問題,就是在頁面載入後又開始執行多個 Ajax 請求,這會發生什麼現象呢?頁面一開始會空空的,然後資訊開始慢慢的呈現出來,這樣的現象會造成兩種問題:
  1. Server 在同一時間會有來自單一位址的大量請求
  2. 使用者的等待時間變長

第一個問題會使 Server 連接端口的負荷增加,雖然在流量上並沒有很大的區別,但卻會考驗 Server 的硬體資源。

第二個問題是使用者必須等待所有 Ajax 回應後才能看到完整的頁面資訊,而且會因為使用者的頻寬成倍數關係。

Ajax 開發所產生的問題

我們會發生這樣的問題,來自於過度使用以 Ajax 為基礎的模組架構,將一些沒必要利用 Ajax 處理的應用,也使用 Ajax 來呈現,Ajax 原先是用來優化呈現上的局部置換,及增加與使用者互動的應用介面,主要是用來避免重新載入已有的資訊,並讓頁面可以有更好的介面輔助,但在習慣 Ajax 的架構時,不知不覺就習慣利用這個架構去作模組的規劃。

所以再利用 Ajax 作開發時,必須考慮到 Ajax 主要的應用目的,不然在過度不當採用這個應用時,會造成更多的問題存在。
2007-09-22 01:15

Ajax 使用 POST 傳送

這篇文章是想要將所學到的 Ajax 做一個簡單的紀錄
這裡再次感謝小正正教室

/* 針對不同瀏覽器的前置處理宣告 */
if (typeof(XMLHttpRequest)=="undefined" && window.ActiveXObject) {
XMLHttpRequest=function(){
var arrSignatures = [
"MSXML2.XMLHTTP.5.0",
"MSXML2.XMLHTTP.4.0",
"MSXML2.XMLHTTP.3.0",
"MSXML2.XMLHTTP",
"Microsoft.XMLHTTP"];
for (var i = 0; i < arrSignatures.length; i++) {
try{
var oRequest = new ActiveXObject(arrSignatures[i]);
return oRequest;
}catch(oError){/*ignore*/}
}
throw new Error("MSXML is not installed on your system.");
};
}

/* 傳送連接 */
function convectionLink(){
/*建立傳送的資料 */
var postData = 'user=xxxx&pass=xxxx';
/*產生要求資料的 URL 位址*/
var sURL = "check_in.php";
/* 建立 XMLHttpRequest 物件,並且送要求 */
var oRequest = new XMLHttpRequest();
/* 設定(傳送的方式,要求的位址,是否非同步進行) */
oRequest.open("POST", sURL, true);
/* 使用 POST 傳送必須設定 MIME 型態 */
oRequest.setRequestHeader(
'Content-Type',
'application/x-www-form-urlencoded'
);

/* 建立接收資料的函數 */
oRequest.onreadystatechange = function(){
/* readyState 所有可能的傳送狀態值如下:
0 (還沒開始)
1 (讀取中)
2 (已讀取)
3 (資訊交換中)
4 (請求完成) */
if (oRequest.readyState == 4) {
/* (在此處加入開啟已停用選項的設置) */
/* 處理傳回為 200 的 HTTP 狀態碼 */
if (oRequest.status == 200) {
/* 接受資料成功 */
/*可以從responseText或responseXML取得傳回的資料*/
json = oRequest.responseText;

/* 處理其他錯誤 HTTP 狀態碼 */
}else{
/*接收資料失敗,可以從 statusText 取得錯誤狀態資訊*/
alert(oRequest.statusText);
}
}
}

/* (在此處可以加入一些網頁選項停用的設置,以防止重複送出) */

/* 送出 Ajax 要求 */
oRequest.send(postData);
/*以POST傳送時,這裡可以輸入(XML,串流,字串,JSON格式)*/
/*以GET傳送時,這裡只要輸入 null 或是空的 */
}


參考網頁:
小正正教室:Ajax 兩層連動選單

相關連結:
爪哇豆的秘密:AJAX深度歷險1(Getting Started)
Ajax内部交流文档
MoztwWiki:AJAX 上手篇
維基百科:AJAX
語言技術:Ajax Gossip