tag:blogger.com,1999:blog-59465307047421309702024-03-06T16:20:07.273+08:00Jax 的工作紀錄除了在整理學習上的經驗,同時也能幫助其他需要的人Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.comBlogger7125tag:blogger.com,1999:blog-5946530704742130970.post-33163877699696296622014-03-05T23:38:00.001+08:002023-02-25T21:32:20.715+08:00利用 HTTP Status Codes 傳遞 Ajax 成功失敗的狀態一般處理 Ajax 回應時會傳送的資訊種類有:資料、成功訊息、錯誤訊息、失敗訊息以及處理狀態,傳遞的資訊種類並不一致,再加上除了資料之外,通常還希望能傳遞處理狀態,這種情況大部分會選擇是以 JSON 的方式傳遞這兩個訊息,以下是常見的幾種格式:<br />
<br />
<pre class="js" name="code">{ code: 1, msg: "OK" }
{ success: true, result: "data", errorMsg: "" }
{ status: 'success', result: [], errorMsg: "" }
//...
</pre><br />
但以執行狀態跟操作行為作一個歸納,可以區分以下幾種回傳結果:<br />
<table class="table_list" cellspacing="0" cellpadding="4" border="1"> <tr class="header">
<th>資料操作</th>
<th>HTTP Method</th>
<th>成功</th>
<th>錯誤/失敗</th>
</tr>
<tr>
<td>檢視(Read)</td>
<td>GET</td>
<td>資料</td>
<td>錯誤/失敗訊息</td>
</tr>
<tr>
<td>新增(Create)<br />
修改(Update)<br />
刪除(Delete)</td>
<td>POST</td>
<td>成功訊息</td>
<td>錯誤/失敗訊息</td>
</tr>
</table><br />
從上面的歸納可以看出規律性,接著只要有方法可以傳送處理的狀態,以及能夠區分資料的種類,其實就單純很多,而 HTTP Status Codes 就是用來傳遞 HTTP 的處理狀態,如果利用這個方式來傳遞自訂的處理狀態,這樣 HTTP Content 就可以很單純傳遞資料,讓資料格式不受限於 JSON,還可以使用其他格式(text, xml, html),而且 XMLHttpRequest 本身就有處理 HTTP Status Codes 的能力,而 jQuery.ajax 也有提供 error status 的處理,所以可以利用這個來定義狀態的處理,在 HTTP Status Codes 有幾個已經定義狀態,很適合用來回傳處理狀態的資訊:<br />
<br />
<table class="table_list" cellspacing="0" cellpadding="4" border="1"> <tr>
<th>400</th>
<td>Bad Request</td>
<td>錯誤的請求</td>
<td>適用在表單內容的錯誤,如必填欄位未填、Email 格式錯誤</td>
</tr>
<tr>
<th>403</th>
<td>Forbidden</td>
<td>沒有權限,被禁止的</td>
<td>適用在沒有登入或權限不足</td>
</tr>
<tr>
<th>500</th>
<td>Internal Server Error</td>
<td>內部服務器錯誤</td>
<td>適用在程式的錯誤</td>
</tr>
</table><br />
<br />
jQuery 接收資訊的範例<br />
<pre class="js" name="code">$.ajax({
type: "POST",
url: document.location,
success: function (data, textStatus, jqXHR) {
alert(data);
},
error: function (jqXHR, textStatus, errorThrown) {
alert(jqXHR.responseText);
}
});
</pre> <br />
<br />
PHP 傳遞錯誤訊息的範例 <br />
<pre class="php" name="code">if (php_sapi_name() == 'cgi'){
header("Status: 400 Bad Request");
}else{
header("HTTP/1.0 400 Bad Request");
}
exit("儲存失敗!!");
</pre><br />
<br />
C# MVC 傳遞錯誤訊息的範例 <br />
<pre class="cs" name="code">Response.TrySkipIisCustomErrors = true;
Response.StatusCode = 400;
return Content("儲存失敗!!");
</pre>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-69953130333786738302009-05-29T02:52:00.011+08:002010-09-24T00:18:20.008+08:00Ajax(XMLHttpRequest) 同步與非同步(異步)連結首先針對 Internet Explorer 的連結物件做統一的處理,將 ActiveXObject 包裝成與 Mozilla 中的 XMLHttpRequest 相同的物件,這樣我們就可以排除瀏覽器的問題。<br /><pre class="js" name="code"><br />/* 針對不同瀏覽器的前置處理宣告 */<br />if (typeof(XMLHttpRequest)=="undefined" && window.ActiveXObject) {<br /> XMLHttpRequest=function(){<br /> var arrSignatures = [<br /> "MSXML2.XMLHTTP.5.0",<br /> "MSXML2.XMLHTTP.4.0",<br /> "MSXML2.XMLHTTP.3.0",<br /> "MSXML2.XMLHTTP",<br /> "Microsoft.XMLHTTP"];<br /> for (var i = 0; i < arrSignatures.length; i++) {<br /> try{<br /> var oRequest = new ActiveXObject(arrSignatures[i]);<br /> return oRequest;<br /> }catch(oError){/*ignore*/}<br /> }<br /> throw new Error("MSXML is not installed on your system.");<br /> };<br />}<br /></pre><br /><br /><br />我們可以直接用 XMLHttpRequest 去處理 Ajax 連結,這是以[GET]方式建立[非同步]的傳送連接,如果要使用 POST 做連結請參考之前的文章[<a href="/2007/09/ajax-post.html">Ajax 使用 POST 傳送</a>]。<br />POST 的差別只在於 open,setRequestHeader,send 這三個地方的設定。<br /><pre class="js" name="code"><br />/**=( 以[GET]方式建立[非同步]傳送連接 )====================*/<br /><br />// 產生要求資料的 URL 及 GET 參數<br />var sURL = "check_in.php?user=xxxx&pass=xxxx";<br /><br />// 建立 XMLHttpRequest 物件,並且送要求 <br />var oRequest = new XMLHttpRequest();<br /><br />// 設定連結方式及位址,並以非同步方式處理<br />oRequest.open("GET", sURL, true);<br />/*<br />void open(<br /> in AUTF8String method, 傳送的方式<br /> in AUTF8String url, 要求的位址<br /> [optional] in boolean async, 同步方式(預設 true 非同步)<br /> [optional] in AString user, 使用者名稱(預設為空字串)<br /> [optional] in AString password 使用者密碼(預設為空字串)<br />);<br />*/<br /><br />// 建立接收狀態的事件處理 <br />oRequest.onreadystatechange = function(){<br />/* <br />當狀態變更時都會呼叫此事件<br />可利用 readyState 取得目前的狀態 <br />所有可能的傳送狀態值如下:<br /> 0 (還沒開始)<br /> 1 (讀取中)<br /> 2 (已讀取)<br /> 3 (資訊交換中)<br /> 4 (請求完成) <br />*/<br /> switch(oRequest.readyState){<br /> case 0: // 開始前的程式處理<br /> break;<br /> case 1: // 讀取中的程式處理<br /> break;<br /> case 2: // 已讀取的程式處理<br /> break;<br /> case 3: // 資訊交換中的程式處理<br /> break;<br /> case 4: // 請求完成的程式處理<br /> /* (在此處加入開啟已停用選項的設置) */<br /> <br /> /*可以從responseText或responseXML取得傳回的資料*/<br /> // 處理傳回為 200 的 HTTP 狀態碼 <br /> if (oRequest.status == 200) {<br /> // 接受資料成功 <br /> <br /> <br /> // 將 responseText 中的文字轉成 JSON 物件<br /> json = eval('('+oRequest.responseText+')');<br /> <br /> // 處理其他錯誤 HTTP 狀態碼 <br /> }else{<br /> /*接收資料失敗,可以從 statusText 取得錯誤狀態資訊*/<br /> alert(oRequest.statusText);<br /> }<br /> break;<br /> } <br /> <br />}<br /><br />/* (在此處可以加入一些網頁選項停用的設置,以防止重複送出) */<br /><br />// 送出 Ajax 要求 <br />oRequest.send(null);<br />/*<br />以POST傳送時,這裡可以輸入(XML,串流,字串,JSON格式)<br />以GET傳送時,這裡只要輸入 null 或是空的<br />*/<br /><br />// 強制中斷 <br />//oRequest.abort();<br />/* 此函數方法可用在必要時,強制終止非同步請求 */<br /></pre><br /><br /><br />建立[同步]的 Ajax 傳送連接只要將 onreadystatechange 裡的程序移到 send 後面就可以了,如果非必要,最好還是不要以[同步]方式做連結,再處理死結的時候會多一些必要的處理,除非保證連結是 100% 正常且可行的。<br /><pre class="js" name="code"><br />/**=( 以[GET]方式建立[同步]傳送連接 )====================*/<br /><br />// 產生要求資料的 URL 及 GET 參數<br />var sURL = "check_in.php?user=xxxx&pass=xxxx";<br /><br />// 建立 XMLHttpRequest 物件,並且送要求 <br />var oRequest = new XMLHttpRequest();<br /><br />// 設定連結方式及位址,並以同步方式處理<br />oRequest.open("GET", sURL, false);<br />/*<br />void open(<br /> in AUTF8String method, 傳送的方式<br /> in AUTF8String url, 要求的位址<br /> [optional] in boolean async, 同步方式(預設 true 非同步)<br /> [optional] in AString user, 使用者名稱(預設為空字串)<br /> [optional] in AString password 使用者密碼(預設為空字串)<br />);<br />*/<br /><br />/* 開始前的程式處理... */<br /><br />/* 讀取中的程式處理... */<br /><br />// 送出 Ajax 要求 <br />oRequest.send(null);<br />/*<br />以POST傳送時,這裡可以輸入(XML,串流,字串,JSON格式)<br />以GET傳送時,這裡只要輸入 null 或是空的<br />*/<br /><br />// 請求完成的程式處理<br />/*可以從responseText或responseXML取得傳回的資料*/<br />// 處理傳回為 200 的 HTTP 狀態碼 <br />if (oRequest.status == 200) {<br /> // 接受資料成功 <br /> <br /> // 將 responseText 中的文字轉成 JSON 物件<br /> json = eval('('+oRequest.responseText+')');<br /><br />// 處理其他錯誤 HTTP 狀態碼 <br />}else{<br /> /*接收資料失敗,可以從 statusText 取得錯誤狀態資訊*/<br /> alert(oRequest.statusText);<br />}<br /></pre><br /><br /><br />參考來源:<br /><a href="https://developer.mozilla.org/En/XMLHttpRequest">XMLHttpRequest - MDC</a><br /><a href="http://hi.baidu.com/lieyu063/blog/item/560ffceaf53276d2d439c9dc.html">XMLHttpRequest的同步请求和Firefox的问题_网银</a><br /><br /><a href="http://blog.xuite.net/jameschih/java/5598706?st=c&re=list&p=1&w=262779">爪哇豆的秘密:AJAX深度歷險1(Getting Started)</a><br /><a href="http://www.dragonson.com/doc/ajax.html">Ajax内部交流文档</a><br /><a href="http://wiki.moztw.org/index.php/AJAX_%E4%B8%8A%E6%89%8B%E7%AF%87">MoztwWiki:AJAX 上手篇</a><br /><a href="http://zh.wikipedia.org/w/index.php?title=AJAX&variant=zh-tw">維基百科:AJAX</a><br /><a href="http://caterpillar.onlyfun.net/Gossip/AjaxGossip/AjaxGossip.html">語言技術:Ajax Gossip<br /></a>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com3tag:blogger.com,1999:blog-5946530704742130970.post-21780290395226376702008-08-20T17:27:00.005+08:002010-05-27T00:30:12.144+08:00Ajax 模組架構的應用<img src="http://3.bp.blogspot.com/_b8lN_UbLoEc/SKlSOivx3AI/AAAAAAAABqQ/_cfqHsKFwNI/s320/Diagram7.png" alt="Ajax 模組架構的應用" id="BLOGGER_PHOTO_ID_5235806451593763842" border="0" /><br />一樣的就之前所提到的問題(<a href="/2008/08/ajax.html">Ajax 開發所產生的問題</a>),這是另一種以模組架構為基礎的方法,模組開發的好處我就不多作說明了,主要的行為模式是:<br /><ol><li>在請求 Page 時就先將 Module Include,讓頁面再第一次讀取時就可以完整呈現。</li><li>在頁面需要執行局部置換時,再利用 Ajax 向 Module 請求局部內容。<br /></li></ol><br />這樣做既不會失去模組開發的優點,也不會有 Ajax 造成的過長等待,讓 Ajax 主要應用在局部置換及 UI 處理。Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-90848553822228922272008-08-19T16:17:00.007+08:002010-05-27T00:30:33.996+08:00利用屏壁來延長頁面的呈現時間就之前提到的問題(<a href="/2008/08/ajax.html">Ajax 開發所產生的問題</a>),這很可能連帶出現以下問題:<br /><ol><li>瀏覽者再頁面尚未完整呈現時誤觸連結,造成錯誤操作。</li><li>功能的初始未完成,瀏覽者再使用上出現無法動作的錯愕情形。</li></ol><br /><br />這些問題可以用一個有效的方法去延長瀏覽者的等待時間,在一開始的頁面裡預設疊上一個遮蓋整個頁面的等待圖示,在 JavaScript 處理完後再移出屏壁,一個很好的範例就是 <a href="http://mail.google.com/mail?hl=zh-TW">Gmail</a>,再一個主要的頁面呈現前,置入一個等待圖示去避免一些可能的不當操作。<br /><br />順帶一提,<a href="http://mail.google.com/mail?hl=zh-TW">Gmail</a> 利用 ifreme 去做出局部置換的效果,這樣做的好處是,瀏覽器會自動去紀錄上下頁,在 Ajax 的應用上瀏覽紀錄這件事是必須額外處理的。Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-2914625823973717612008-08-18T17:27:00.007+08:002010-05-27T00:31:09.831+08:00利用 Ajax 減少 Server 運算量在 Ajax 還沒有出現時 JavaScript 本身就可以執行許多計算方面的程式了,像之前的文章『<a href="/2008/05/javascript-html-diff.html">HTML 比較(diff)</a>』、『<a href="/2007/06/sudoku.html">數獨(sudoku)解題</a>』、『<a href="/2007/10/blog-post_13.html">線性代數-計算機</a>』等都是利用 JavaScript 去達成的計算程式,象 Yahoo 也有在 Login 時利用 JavaScript 做 md5 的計算,其實瀏覽器還是可以做一些有規模的運算。<br /><br /><img src="http://4.bp.blogspot.com/_b8lN_UbLoEc/SKkpXV3zndI/AAAAAAAABqI/rAxR_goeX9U/%E5%9C%96%E8%A1%A86.png" alt="利用 Ajax 減少 Server 運算量" id="BLOGGER_PHOTO_ID_5235761522779856338" border="0" /><br /><br />主要是將運算資料取回,計算結果明細後,再跟 Server 取得剩餘的詳細資料,這個架構可以讓 Server 原本的運算量轉由瀏覽器執行,是一個以空間換時間的作法,當然有一好沒兩好,沒錯這樣的方法明顯會發生之前所說的問題(<a href="/2008/08/ajax.html">Ajax 開發所產生的問題</a>),是否要用這個方法就看各位的考量了。<br /><br />其中特別要注意的一些事項:<br /><ol><li style="color: rgb(255, 0, 0);">再資訊必須是即時性,且運算量大於一定時間以上時,考慮這種架構才會有意義,要不然只會浪費頻寬。</li><li style="color: rgb(255, 0, 0);">資料安全性問題,必須定義哪些瀏覽者可以取得計算資料,要不然會造成嚴重的漏洞。</li><li style="color: rgb(255, 0, 0);">資料量的大小,太大的資料可能會造成瀏覽器整個當掉,再規劃時要特別注意最大上限,至於詳細的範圍要依瀏覽者的設備而定。</li></ol>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-71418055776103248362008-08-14T16:17:00.006+08:002013-06-11T21:08:41.669+08:00Ajax 開發所產生的問題在 <a target="_blank" href="http://www.wacanai.com/">wacanai</a> 的開發中發現了一個問題,就是在頁面載入後又開始執行多個 Ajax 請求,這會發生什麼現象呢?頁面一開始會空空的,然後資訊開始慢慢的呈現出來,這樣的現象會造成兩種問題:<br />
<ol><li style="color: rgb(255, 0, 0);">Server 在同一時間會有來自單一位址的大量請求</li>
<li style="color: rgb(255, 0, 0);">使用者的等待時間變長</li>
</ol><br />
第一個問題會使 Server 連接端口的負荷增加,雖然在流量上並沒有很大的區別,但卻會考驗 Server 的硬體資源。<br />
<br />
第二個問題是使用者必須等待所有 Ajax 回應後才能看到完整的頁面資訊,而且會因為使用者的頻寬成倍數關係。<br />
<br />
<img src="http://4.bp.blogspot.com/_b8lN_UbLoEc/SKP8PCficjI/AAAAAAAABpY/BBqNJjT_mV8/%E5%9C%96%E8%A1%A81.png" alt="Ajax 開發所產生的問題" id="BLOGGER_PHOTO_ID_5234304527232037426" border="0" /><br />
<br />
我們會發生這樣的問題,來自於過度使用以 Ajax 為基礎的模組架構,將一些沒必要利用 Ajax 處理的應用,也使用 Ajax 來呈現,Ajax 原先是用來優化呈現上的<span style="color: rgb(255, 0, 0);">局部置換</span>,及增加與使用者互動的<span style="color: rgb(255, 0, 0);">應用介面</span>,主要是用來避免重新載入已有的資訊,並讓頁面可以有更好的介面輔助,但在習慣 Ajax 的架構時,不知不覺就習慣利用這個架構去作模組的規劃。<br />
<br />
所以再利用 Ajax 作開發時,必須考慮到 Ajax 主要的應用目的,不然在過度不當採用這個應用時,會造成更多的問題存在。Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com0tag:blogger.com,1999:blog-5946530704742130970.post-47183178196637566412007-09-22T01:15:00.006+08:002010-09-24T00:18:37.251+08:00Ajax 使用 POST 傳送這篇文章是想要將所學到的 Ajax 做一個簡單的紀錄<br />這裡再次感謝<a href="http://tw.myblog.yahoo.com/class2u-com/">小正正教室</a>。<br /><pre class="js" name="code"><br />/* 針對不同瀏覽器的前置處理宣告 */<br />if (typeof(XMLHttpRequest)=="undefined" && window.ActiveXObject) {<br /> XMLHttpRequest=function(){<br /> var arrSignatures = [<br /> "MSXML2.XMLHTTP.5.0",<br /> "MSXML2.XMLHTTP.4.0",<br /> "MSXML2.XMLHTTP.3.0",<br /> "MSXML2.XMLHTTP",<br /> "Microsoft.XMLHTTP"];<br /> for (var i = 0; i < arrSignatures.length; i++) {<br /> try{<br /> var oRequest = new ActiveXObject(arrSignatures[i]);<br /> return oRequest;<br /> }catch(oError){/*ignore*/}<br /> }<br /> throw new Error("MSXML is not installed on your system.");<br /> };<br />}<br /><br />/* 傳送連接 */<br />function convectionLink(){<br /> /*建立傳送的資料 */<br /> var postData = 'user=xxxx&pass=xxxx';<br /> /*產生要求資料的 URL 位址*/<br /> var sURL = "check_in.php";<br /> /* 建立 XMLHttpRequest 物件,並且送要求 */<br /> var oRequest = new XMLHttpRequest();<br /> /* 設定(傳送的方式,要求的位址,是否非同步進行) */<br /> oRequest.open("POST", sURL, true);<br /> /* 使用 POST 傳送必須設定 MIME 型態 */<br /> oRequest.setRequestHeader(<br /> 'Content-Type',<br /> 'application/x-www-form-urlencoded'<br /> );<br /><br /> /* 建立接收資料的函數 */<br /> oRequest.onreadystatechange = function(){<br /> /* readyState 所有可能的傳送狀態值如下:<br /> 0 (還沒開始)<br /> 1 (讀取中)<br /> 2 (已讀取)<br /> 3 (資訊交換中)<br /> 4 (請求完成) */<br /> if (oRequest.readyState == 4) {<br /> /* (在此處加入開啟已停用選項的設置) */<br /> /* 處理傳回為 200 的 HTTP 狀態碼 */<br /> if (oRequest.status == 200) {<br /> /* 接受資料成功 */<br /> /*可以從responseText或responseXML取得傳回的資料*/<br /> json = oRequest.responseText;<br /><br /> /* 處理其他錯誤 HTTP 狀態碼 */<br /> }else{<br /> /*接收資料失敗,可以從 statusText 取得錯誤狀態資訊*/<br /> alert(oRequest.statusText);<br /> }<br /> }<br /> }<br /><br /> /* (在此處可以加入一些網頁選項停用的設置,以防止重複送出) */<br /><br /> /* 送出 Ajax 要求 */<br /> oRequest.send(postData);<br /> /*以POST傳送時,這裡可以輸入(XML,串流,字串,JSON格式)*/<br /> /*以GET傳送時,這裡只要輸入 null 或是空的 */<br />}<br /></pre><br /><br />參考網頁:<br /><a href="http://tw.myblog.yahoo.com/class2u-com/article?mid=2">小正正教室:Ajax 兩層連動選單</a><br /><br />相關連結:<br /><a href="http://blog.xuite.net/jameschih/java/5598706?st=c&re=list&p=1&w=262779">爪哇豆的秘密:AJAX深度歷險1(Getting Started)</a><br /><a href="http://www.dragonson.com/doc/ajax.html">Ajax内部交流文档</a><br /><a href="http://wiki.moztw.org/index.php/AJAX_%E4%B8%8A%E6%89%8B%E7%AF%87">MoztwWiki:AJAX 上手篇</a><br /><a href="http://zh.wikipedia.org/w/index.php?title=AJAX&variant=zh-tw">維基百科:AJAX</a><br /><a href="http://caterpillar.onlyfun.net/Gossip/AjaxGossip/AjaxGossip.html">語言技術:Ajax Gossip<br /></a>Jax Huhttp://www.blogger.com/profile/01953021685585893658noreply@blogger.com2