摘要:基于標(biāo)準(zhǔn)被廣泛支持。這樣的類最初是在中作為一個(gè)名為的對(duì)象引入的。請(qǐng)求還沒有被發(fā)送。當(dāng)為,這個(gè)屬性返回目前已經(jīng)接收的響應(yīng)部分。由服務(wù)器返回的狀態(tài)代碼,如表示成功,而表示錯(cuò)誤。方法取消當(dāng)前響應(yīng),關(guān)閉連接并且結(jié)束任何未決的網(wǎng)絡(luò)活動(dòng)。
前言
總括: 本文講解了ajax的歷史,工作原理以及優(yōu)缺點(diǎn),對(duì)XMLHttpRequest對(duì)象進(jìn)行了詳細(xì)的講解,并使用原生js實(shí)現(xiàn)了一個(gè)ajax對(duì)象以方便日常開始使用。
damonare的ajax庫(kù):damonare的ajax庫(kù)
原文博客地址:你真的懂a(chǎn)jax嗎?
知乎專欄&&簡(jiǎn)書專題:前端進(jìn)擊者(知乎)&&前端進(jìn)擊者(簡(jiǎn)書)
博主博客地址:Damonare的個(gè)人博客
古之立大事者,不惟有超世之才,亦必有堅(jiān)忍不拔之志。
正文相信每個(gè)前端程序員日常工作中都避免不了的工作就是和后端聯(lián)調(diào),聯(lián)調(diào)自然就避免不了使用ajax,但我相信,不管是使用jquery封裝的ajax方法還是使用vue的插件vue-resource的程序員,真正對(duì)于ajax有過深入探究的并不多,我們更多的是為了使用而使用,至于它的原理往往因?yàn)榧词共涣私庖琅f能做出東西而懶得去看,我們都被輪子們慣壞了。根據(jù)二八定律,即任何一組東西中,最重要的只占其中一小部分,約20%,其余80%的盡管是多數(shù),卻是次要的。因 此,如果想擠進(jìn)那20%的行列,就要學(xué)到一般人學(xué)不到的深度,學(xué)到一般人學(xué)不了的東西。
好的,現(xiàn)在我們從頭來說一下ajax。
Ajax簡(jiǎn)介在上世紀(jì)90年代,幾乎所有的網(wǎng)站都由HTML頁(yè)面實(shí)現(xiàn),服務(wù)器處理每一個(gè)用戶請(qǐng)求都需要重新加載網(wǎng)頁(yè)。形式是怎樣的呢?就比如說你在瀏覽器上登錄自己的微博賬號(hào),填完了表單,點(diǎn)擊登錄按鈕,一次"完整"的HTTP請(qǐng)求就此觸發(fā),服務(wù)器發(fā)現(xiàn)你的登錄密碼不對(duì)頭,立馬把網(wǎng)頁(yè)原原本本的返回給你,在用戶看來呢,就是一次重新加載的過程!用戶體驗(yàn)極差!而且這個(gè)做法浪費(fèi)了許多帶寬,因?yàn)樵谇昂髢蓚€(gè)頁(yè)面中的大部分HTML碼往往是相同的。由于每次應(yīng)用的溝通都需要向服務(wù)器發(fā)送請(qǐng)求,應(yīng)用的回應(yīng)時(shí)間依賴于服務(wù)器的回應(yīng)時(shí)間。這導(dǎo)致了用戶界面的回應(yīng)比本機(jī)應(yīng)用慢得多。
到了2005年,google率先在它的應(yīng)用(諸如google地圖、gmail)里使用了ajax技術(shù),這才讓這項(xiàng)技術(shù)正式風(fēng)靡開來。
如今它的應(yīng)用已經(jīng)十分廣泛:
運(yùn)用XHTML+CSS來表達(dá)信息;
運(yùn)用JavaScript操作DOM(Document Object Model)來運(yùn)行動(dòng)態(tài)效果;
運(yùn)用XML和XSLT操作數(shù)據(jù);
運(yùn)用XMLHttpRequest或新的Fetch API與網(wǎng)頁(yè)服務(wù)器進(jìn)行異步數(shù)據(jù)交換;
注意:AJAX與Flash、Silverlight和Java Applet等RIA技術(shù)是有區(qū)分的。
Ajax工作原理?Ajax的工作原理相當(dāng)于在用戶和服務(wù)器之間加了一個(gè)中間層(ajax引擎),使用戶操作與服務(wù)器響應(yīng)異步化。并不是所有的用戶請(qǐng)求都提交給服務(wù)器,像—些數(shù)據(jù)驗(yàn)證(比如判斷用戶是否輸入了數(shù)據(jù))和數(shù)據(jù)處理(比如判斷用戶輸入數(shù)據(jù)是否是數(shù)字)等都交給Ajax引擎自己來做,?只有確定需要從服務(wù)器讀取新數(shù)據(jù)時(shí)再由Ajax引擎代為向服務(wù)器提交請(qǐng)求。把這些交給了Ajax引擎,用戶操作起來也就感覺更加流暢了。
Ajax優(yōu)缺點(diǎn) Ajax的優(yōu)點(diǎn)無刷新更新數(shù)據(jù)。
AJAX最大優(yōu)點(diǎn)就是能在不刷新整個(gè)頁(yè)面的前提下與服務(wù)器通信維護(hù)數(shù)據(jù)。這使得Web應(yīng)用程序更為迅捷地響應(yīng)用戶交互,并避免了在網(wǎng)絡(luò)上發(fā)送那些沒有改變的信息,減少用戶等待時(shí)間,帶來非常好的用戶體驗(yàn)。
2.異步與服務(wù)器通信。
AJAX使用異步方式與服務(wù)器通信,不需要打斷用戶的操作,具有更加迅速的響應(yīng)能力。優(yōu)化了Browser和Server之間的溝通,減少不必要的數(shù)據(jù)傳輸、時(shí)間及降低網(wǎng)絡(luò)上數(shù)據(jù)流量。
3.前端和后端負(fù)載平衡。
AJAX可以把以前一些服務(wù)器負(fù)擔(dān)的工作轉(zhuǎn)嫁到客戶端,利用客戶端閑置的能力來處理,減輕服務(wù)器和帶寬的負(fù)擔(dān),節(jié)約空間和寬帶租用成本。并且減輕服務(wù)器的負(fù)擔(dān),AJAX的原則是“按需取數(shù)據(jù)”,可以最大程度的減少冗余請(qǐng)求和響應(yīng)對(duì)服務(wù)器造成的負(fù)擔(dān),提升站點(diǎn)性能。
4.基于標(biāo)準(zhǔn)被廣泛支持。
AJAX基于標(biāo)準(zhǔn)化的并被廣泛支持的技術(shù),不需要下載瀏覽器插件或者小程序,但需要客戶允許JavaScript在瀏覽器上執(zhí)行。隨著Ajax的成熟,一些簡(jiǎn)化Ajax使用方法的程序庫(kù)也相繼問世。同樣,也出現(xiàn)了另一種輔助程序設(shè)計(jì)的技術(shù),為那些不支持JavaScript的用戶提供替代功能。
5.界面與應(yīng)用分離。
Ajax使WEB中的界面與應(yīng)用分離(也可以說是數(shù)據(jù)與呈現(xiàn)分離),有利于分工合作、減少非技術(shù)人員對(duì)頁(yè)面的修改造成的WEB應(yīng)用程序錯(cuò)誤、提高效率、也更加適用于現(xiàn)在的發(fā)布系統(tǒng)。
Ajax缺點(diǎn)AjAX干掉了Back和加入收藏書簽功能,即對(duì)瀏覽器機(jī)制的破壞。
對(duì)應(yīng)用Ajax最主要的批評(píng)就是,它可能破壞瀏覽器的后退與加入收藏書簽功能。在動(dòng)態(tài)更新頁(yè)面的情況下,用戶無法回到前一個(gè)頁(yè)面狀態(tài),這是因?yàn)闉g覽器僅能記下歷史記錄中的靜態(tài)頁(yè)面。一個(gè)被完整讀入的頁(yè)面與一個(gè)已經(jīng)被動(dòng)態(tài)修改過的頁(yè)面之間的可能差別非常微妙;用戶通常都希望單擊后退按鈕,就能夠取消他們的前一次操作,但是在Ajax應(yīng)用程序中,卻無法這樣做。不過開發(fā)者已想出了種種辦法來解決這個(gè)問題,HTML5?之前的方法大多是在用戶單擊后退按鈕訪問歷史記錄時(shí),通過創(chuàng)建或使用一個(gè)隱藏的IFRAME來重現(xiàn)頁(yè)面上的變更。(例如,當(dāng)用戶在Google Maps中單擊后退時(shí),它在一個(gè)隱藏的IFRAME中進(jìn)行搜索,然后將搜索結(jié)果反映到Ajax元素上,以便將應(yīng)用程序狀態(tài)恢復(fù)到當(dāng)時(shí)的狀態(tài))。
關(guān)于無法將狀態(tài)加入收藏或書簽的問題,HTML5之前的一種方式是使用URL片斷標(biāo)識(shí)符(通常被稱為錨點(diǎn),即URL中#后面的部分)來保持追蹤,允許用戶回到指定的某個(gè)應(yīng)用程序狀態(tài)。(許多瀏覽器允許JavaScript動(dòng)態(tài)更新錨點(diǎn),這使得Ajax應(yīng)用程序能夠在更新顯示內(nèi)容的同時(shí)更新錨點(diǎn)。)HTML5?以后可以直接操作瀏覽歷史,并以字符串形式存儲(chǔ)網(wǎng)頁(yè)狀態(tài),將網(wǎng)頁(yè)加入網(wǎng)頁(yè)收藏夾或書簽時(shí)狀態(tài)會(huì)被隱形地保留。上述兩個(gè)方法也可以同時(shí)解決無法后退的問題。
2.AJAX的安全問題。
AJAX技術(shù)給用戶帶來很好的用戶體驗(yàn)的同時(shí)也對(duì)IT企業(yè)帶來了新的安全威脅,Ajax技術(shù)就如同對(duì)企業(yè)數(shù)據(jù)建立了一個(gè)直接通道。這使得開發(fā)者在不經(jīng)意間會(huì)暴露比以前更多的數(shù)據(jù)和服務(wù)器邏輯。Ajax的邏輯可以對(duì)客戶端的安全掃描技術(shù)隱藏起來,允許黑客從遠(yuǎn)端服務(wù)器上建立新的攻擊。還有Ajax也難以避免一些已知的安全弱點(diǎn),諸如跨站點(diǎn)腳步攻擊、SQL注入攻擊和基于Credentials的安全漏洞等等。
3.因?yàn)榫W(wǎng)絡(luò)延遲需要給用戶提供必要提示
進(jìn)行Ajax開發(fā)時(shí),網(wǎng)絡(luò)延遲——即用戶發(fā)出請(qǐng)求到服務(wù)器發(fā)出響應(yīng)之間的間隔——需要慎重考慮。如果不給予用戶明確的回應(yīng),沒有恰當(dāng)?shù)念A(yù)讀數(shù)據(jù),或者對(duì)XMLHttpRequest的不恰當(dāng)處理,都會(huì)使用戶感到厭煩。通常的解決方案是,使用一個(gè)可視化的組件來告訴用戶系統(tǒng)正在進(jìn)行后臺(tái)操作并且正在讀取數(shù)據(jù)和內(nèi)容。
XMLhttpRequest介紹Ajax(Asynchronous JavaScript and XML)不是指一種單一的技術(shù),而是有機(jī)地利用了一系列相關(guān)的技術(shù)。雖然其名稱包含XML,但實(shí)際上數(shù)據(jù)格式可以由JSON代替,進(jìn)一步減少數(shù)據(jù)量,形成所謂的AJAJ。為了使用JavaScript向服務(wù)器發(fā)出?HTTP?請(qǐng)求,需要一個(gè)提供此功能的類的實(shí)例。這就是XMLHttpRequest的由來。這樣的類最初是在Internet Explorer中作為一個(gè)名為XMLHTTP的ActiveX對(duì)象引入的。然后,Mozilla,Safari和其他瀏覽器,實(shí)現(xiàn)一個(gè)XMLHttpRequest類,支持Microsoft的原始ActiveX對(duì)象的方法和屬性。同時(shí)微軟也實(shí)現(xiàn)了XMLHttpRequest。
顯而易見XMLHttpRequest類是重中之重了。
XMLhttpRequest屬性一個(gè)JavaScript函數(shù)對(duì)象,當(dāng)readyState屬性改變時(shí)會(huì)調(diào)用它。回調(diào)函數(shù)會(huì)在user interface線程中調(diào)用。
HTTP 請(qǐng)求的狀態(tài).當(dāng)一個(gè) XMLHttpRequest 初次創(chuàng)建時(shí),這個(gè)屬性的值從 0 開始,直到接收到完整的 HTTP 響應(yīng),這個(gè)值增加到 4。
5 個(gè)狀態(tài)中每一個(gè)都有一個(gè)相關(guān)聯(lián)的非正式的名稱,下表列出了狀態(tài)、名稱和含義:
狀態(tài) | 名稱 | 描述 |
---|---|---|
0 | Uninitialized | 初始化狀態(tài)。XMLHttpRequest 對(duì)象已創(chuàng)建或已被 abort() 方法重置。 |
1 | Open | open() 方法已調(diào)用,但是 send() 方法未調(diào)用。請(qǐng)求還沒有被發(fā)送。 |
2 | Sent | Send() 方法已調(diào)用,HTTP 請(qǐng)求已發(fā)送到 Web 服務(wù)器。未接收到響應(yīng)。 |
3 | Receiving | 所有響應(yīng)頭部都已經(jīng)接收到。響應(yīng)體開始接收但未完成。 |
4 | Loaded | HTTP 響應(yīng)已經(jīng)完全接收。 |
readyState 的值不會(huì)遞減,除非當(dāng)一個(gè)請(qǐng)求在處理過程中的時(shí)候調(diào)用了 abort() 或 open() 方法。每次這個(gè)屬性的值增加的時(shí)候,都會(huì)觸發(fā) onreadystatechange 事件句柄。
目前為止為服務(wù)器接收到的響應(yīng)體(不包括頭部),或者如果還沒有接收到數(shù)據(jù)的話,就是空字符串。
如果 readyState 小于 3,這個(gè)屬性就是一個(gè)空字符串。當(dāng) readyState 為 3,這個(gè)屬性返回目前已經(jīng)接收的響應(yīng)部分。如果 readyState 為 4,這個(gè)屬性保存了完整的響應(yīng)體。
如果響應(yīng)包含了為響應(yīng)體指定字符編碼的頭部,就使用該編碼。否則,假定使用 Unicode UTF-8。
對(duì)請(qǐng)求的響應(yīng),解析為 XML 并作為?Document 對(duì)象返回。
由服務(wù)器返回的?HTTP 狀態(tài)代碼,如 200 表示成功,而 404 表示 "Not Found" 錯(cuò)誤。當(dāng) readyState 小于 3 的時(shí)候讀取這一屬性會(huì)導(dǎo)致一個(gè)異常。
這個(gè)屬性用名稱而不是數(shù)字指定了請(qǐng)求的 HTTP 的狀態(tài)代碼。也就是說,當(dāng)狀態(tài)為 200 的時(shí)候它是 "OK",當(dāng)狀態(tài)為 404 的時(shí)候它是 "Not Found"。和 status 屬性一樣,當(dāng) readyState 小于 3 的時(shí)候讀取這一屬性會(huì)導(dǎo)致一個(gè)異常。
XMLHttpRequest方法取消當(dāng)前響應(yīng),關(guān)閉連接并且結(jié)束任何未決的網(wǎng)絡(luò)活動(dòng)。
這個(gè)方法把 XMLHttpRequest 對(duì)象重置為 readyState 為 0 的狀態(tài),并且取消所有未決的網(wǎng)絡(luò)活動(dòng)。例如,如果請(qǐng)求用了太長(zhǎng)時(shí)間,而且響應(yīng)不再必要的時(shí)候,可以調(diào)用這個(gè)方法。
把 HTTP 響應(yīng)頭部作為未解析的字符串返回。
如果 readyState 小于 3,這個(gè)方法返回 null。否則,它返回服務(wù)器發(fā)送的所有 HTTP 響應(yīng)的頭部。頭部作為單個(gè)的字符串返回,一行一個(gè)頭部。每行用換行符 "rn" 隔開。
返回指定的 HTTP 響應(yīng)頭部的值。其參數(shù)是要返回的 HTTP 響應(yīng)頭部的名稱。可以使用任何大小寫來制定這個(gè)頭部名字,和響應(yīng)頭部的比較是不區(qū)分大小寫的。
該方法的返回值是指定的 HTTP 響應(yīng)頭部的值,如果沒有接收到這個(gè)頭部或者 readyState 小于 3 則為空字符串。如果接收到多個(gè)有指定名稱的頭部,這個(gè)頭部的值被連接起來并返回,使用逗號(hào)和空格分隔開各個(gè)頭部的值。
初始化一個(gè)請(qǐng)求. 該方法用于JavaScript代碼中;如果是本地代碼, 使用?openRequest())方法代替.
注意:?在一個(gè)已經(jīng)激活的request下(已經(jīng)調(diào)用open()或者openRequest()方法的request)再次調(diào)用這個(gè)方法相當(dāng)于調(diào)用了abort()方法。
參數(shù)
method
請(qǐng)求所使用的HTTP方法; 例如?"GET", "POST", "PUT", "DELETE"等. 如果下個(gè)參數(shù)是非HTTP(S)的URL,則忽略該參數(shù).
url
該請(qǐng)求所要訪問的URL
async
一個(gè)可選的布爾值參數(shù),默認(rèn)為true,意味著是否執(zhí)行異步操作,如果值為false,則send()方法不會(huì)返回任何東西,直到接受到了服務(wù)器的返回?cái)?shù)據(jù)。如果為值為true,一個(gè)對(duì)開發(fā)者透明的通知會(huì)發(fā)送到相關(guān)的事件監(jiān)聽者。這個(gè)值必須是true,如果multipart 屬性是true,否則將會(huì)出現(xiàn)一個(gè)意外。
user
用戶名,可選參數(shù),為授權(quán)使用;默認(rèn)參數(shù)為空string.
password
密碼,可選參數(shù),為授權(quán)使用;默認(rèn)參數(shù)為空string.
發(fā)送 HTTP 請(qǐng)求,使用傳遞給 open() 方法的參數(shù),以及傳遞給該方法的可選請(qǐng)求體。
向一個(gè)打開但未發(fā)送的請(qǐng)求設(shè)置或添加一個(gè) HTTP 請(qǐng)求(設(shè)置請(qǐng)求頭)。
參數(shù)
header
將要被賦值的請(qǐng)求頭名稱
value
給指定的請(qǐng)求頭賦的值
Ajax原生js實(shí)現(xiàn)下面是使用原生js寫的ajax:
var ajax = {}; ajax.httpRequest = function () { //判斷是否支持XMLHttpRequest對(duì)象 if (window.XMLHttpRequest) { return new XMLHttpRequest(); } //兼容IE瀏覽器 var versions = [ "MSXML2.XmlHttp.6.0", "MSXML2.XmlHttp.5.0", "MSXML2.XmlHttp.4.0", "MSXML2.XmlHttp.3.0", "MSXML2.XmlHttp.2.0", "Microsoft.XmlHttp" ]; //定義局部變量xhr,儲(chǔ)存IE瀏覽器的ActiveXObject對(duì)象 var xhr; for (var i = 0; i < versions.length; i++) { try { xhr = new ActiveXObject(versions[i]); break; } catch (e) { } } return xhr; }; ajax.send = function (url, callback, method, data, async) { //默認(rèn)異步 if (async === undefined) { async = true; } var httpRequest = ajax.httpRequest(); //初始化HTTP請(qǐng)求 httpRequest.open(method, url, async); //onreadystatechange函數(shù)對(duì)象 httpRequest.onreadystatechange = function () { //readyState 的值等于4,從服務(wù)器拿到了數(shù)據(jù) if (httpRequest.readyState == 4) { //回調(diào)服務(wù)器響應(yīng)數(shù)據(jù) callback(httpRequest.responseText) } }; if (method == "POST") { //給指定的HTTP請(qǐng)求頭賦值 httpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); } //發(fā)送HTTP請(qǐng)求 httpRequest.send(data); }; //實(shí)現(xiàn)GET請(qǐng)求 ajax.get = function (url, data, callback, async) { var query = []; for (var key in data) { query.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key])); } ajax.send(url + (query.length ? "?" + query.join("&") : ""), callback, "GET", null, async) }; //實(shí)現(xiàn)POST請(qǐng)求 ajax.post = function (url, data, callback, async) { var query = []; for (var key in data) { query.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key])); } ajax.send(url, callback, "POST", query.join("&"), async) };
如果你使用jquery或是zepto很大部分是因?yàn)樗腶jax兼容性高的緣故,不妨試試這個(gè):damonare的ajax庫(kù),喜歡給個(gè)star也是可以的。
后記ajax技術(shù)對(duì)于整個(gè)web應(yīng)用意義都是非凡的,僅以此篇致敬那些曾經(jīng)奮斗在一線為了ajax技術(shù)的實(shí)現(xiàn)和普及做出工作的前輩們。
參考文章Ajax工作原理記優(yōu)缺點(diǎn)
Ajax
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/81272.html
摘要:個(gè)人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現(xiàn)在已經(jīng)一年的時(shí)間了,由于工作比較忙,更新緩慢,后面還是會(huì)繼更新,現(xiàn)將已經(jīng)寫好的文章整理一個(gè)目錄,方便更多的小伙伴去學(xué)習(xí)。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個(gè)人前端文章整理 從最開始萌生寫文章的想法,到著手...
摘要:回調(diào)使用封裝入門回調(diào)是啥看這里回調(diào)是什么方應(yīng)杭知乎是一種特殊的函數(shù),這個(gè)函數(shù)被作為參數(shù)傳給另一個(gè)函數(shù)去調(diào)用。 回調(diào)、使用Promise封裝ajax()、Promise入門 1 回調(diào)是啥 call a functioncall a function back callback 看這里:Callback(回調(diào))是什么?---方應(yīng)杭知乎 callback 是一種特殊的函數(shù),這個(gè)函數(shù)被作為參數(shù)...
摘要:入門之建立對(duì)象今天幫朋友寫了一個(gè)簡(jiǎn)單的的發(fā)現(xiàn)了一些東西,決定寫一篇文章記錄一下,避免以后挖坑。函數(shù)會(huì)啟動(dòng)一個(gè)請(qǐng)求但并不是發(fā)送,可以看作辦事之前的準(zhǔn)備。小結(jié)這是一個(gè)手動(dòng)創(chuàng)建對(duì)象并使用最簡(jiǎn)單的方法。 ajax入門之建立XHR對(duì)象 今天幫朋友寫了一個(gè)簡(jiǎn)單的ajax的demo,發(fā)現(xiàn)了一些東西,決定寫一篇文章記錄一下,避免以后挖坑。 創(chuàng)建XMLHttpRequest 通常 functio...
摘要:一是什么的全稱是,其中,是異步的意思。一定要注意如果請(qǐng)求是請(qǐng)求格式必須設(shè)置請(qǐng)求頭字符串拼接模板字符串 一、ajax是什么? 1、ajax?的全稱是Asynchronous?JavaScript?and?XML,其中,Asynchronous?是異步的意思。 2、是7種技術(shù)的綜合,它包含了:JavaScript、xml、xstl、xhtml、dom、 xmlhttprequest、cs...
摘要:不會(huì)給后端發(fā)送請(qǐng)求。只會(huì)復(fù)制粘貼,原理啥的也不了解,現(xiàn)在的項(xiàng)目是用,但是是以為基礎(chǔ)的,所以先學(xué)一波。可以做到局部刷新,無需重新刷新頁(yè)面,擁有更好的用戶體驗(yàn)。具體的優(yōu)缺點(diǎn)可以看后面的鏈接,里面還詳講了三次握手和請(qǐng)求的優(yōu)缺點(diǎn) 不會(huì)給后端發(fā)送請(qǐng)求。只會(huì)復(fù)制粘貼,原理啥的也不了解,現(xiàn)在的項(xiàng)目是用axios,但是axios是以Ajax+Promise為基礎(chǔ)的,所以先學(xué)一波Ajax。Ajax可以做...
閱讀 3482·2021-11-08 13:30
閱讀 3588·2019-08-30 15:55
閱讀 695·2019-08-29 15:16
閱讀 1755·2019-08-26 13:57
閱讀 2104·2019-08-26 12:18
閱讀 800·2019-08-26 11:36
閱讀 1741·2019-08-26 11:30
閱讀 3035·2019-08-23 16:46