問題描述
我有基于服務(wù)器響應(yīng)更新頁面的 AJAX 應(yīng)用程序.AJAX服務(wù)器響應(yīng)所基于的命令需要很長時(shí)間才能生成完整的響應(yīng),但是一旦計(jì)算出來它就會(huì)發(fā)送部分信息.此部分響應(yīng)/部分信息以突發(fā)"形式發(fā)送,并且每個(gè)突發(fā)的時(shí)間和大小是不可預(yù)測(cè)的.將命令輸出流式傳輸?shù)?Web 瀏覽器(到 AJAX 請(qǐng)求)的 CGI 腳本(在 Perl 中)已打開自動(dòng)刷新.
I have AJAX app which updates page based on server response. The command that AJAX server response is based on takes long time to generate full response, but it sends partial information as soon as it is calculated. This partial response / partial info is send in "burst", and time and size of each burst is unpredictable. CGI script (in Perl) that streams command output to web browser (to AJAX request) has autoflush turned on.
服務(wù)器響應(yīng)基于外部命令的輸出.'time cmd >/dev/null' 平均給出大約 10.0 秒,'time cmd | head >/dev/null' 給出不到 0.1 秒(例如數(shù)據(jù)).所有數(shù)據(jù)都是單次調(diào)用此外部命令的結(jié)果.
The server response is based on output of external command. While 'time cmd > /dev/null" gives around 10.0 seconds on average, 'time cmd | head > /dev/null' gives less than 0.1 seconds (for example data). All data is result of single call to this external command.
情況如下(ASCII-藝術(shù)圖如下):
client | | server
--------- ---------
request -
->
/- response
/ .
/ .
/ /- .
<-/ / .
/ .
/ /- [end]
<-/ /
/
/
<-/
我有幾個(gè)關(guān)于這個(gè)問題的問題.
I have a few questions about this problem.
注意:服務(wù)器端在 Perl 中作為 CGI 腳本完成,我更希望看到(也)解決方案,而不使用像 jQuery 這樣的 JavaScript 庫/框架.
Note: server side is done as CGI script in Perl, and I would prefer to see (also) solution without using JavaScript library / framework like jQuery.
AJAX 應(yīng)用服務(wù)器端使用的命令輸出是基于行的.每組線,以一種定義的線開始,以另一種線結(jié)束,由獨(dú)立且不可更改的數(shù)據(jù)組成.我應(yīng)該只是將來自命令的響應(yīng)流式傳輸為text/plain"并在客戶端用 JavaScript 進(jìn)行處理,還是應(yīng)該在服務(wù)器上預(yù)處理數(shù)據(jù),并使用application/json"mimetype 將整個(gè)數(shù)據(jù)塊作為 JSON 發(fā)送?
The output of command used by server side of AJAX app is line based. Each group of lines, beginning with one defined kind of line, and ending with other kind of line, consist of independend and unchangeable data. Should I just stream response from a command as 'text/plain' and do processing in JavaScript on client side, or should I pre-process data on server, and send whole chunks of data as JSON using 'application/json' mimetype?
可能會(huì)發(fā)生服務(wù)器一次發(fā)送的大量數(shù)據(jù)之后很快就會(huì)有另一塊數(shù)據(jù)的情況.如何處理 onreadystatechange
處理程序被調(diào)用而先前的調(diào)用沒有完成工作的情況?我應(yīng)該使用全局變量作為信號(hào)量,還是將狀態(tài)變量作為處理程序參數(shù)傳遞(好吧,使用 xhr.onreadystatechange = function() { handleRequest(xhr, state) }
)?
It might happen that large chunk of data send at once by server is followed soon by another chunk of data. How to deal with situation when onreadystatechange
handler is invoked while previous invocation didn't finished work? Should I use global variable as semaphore, or pass state variable as handler parameter (well, use xhr.onreadystatechange = function() { handleRequest(xhr, state) }
)?
我應(yīng)該使用text/plain"還是application/json",或者可能是multipart/x0mixed-replace"?注意:這個(gè)應(yīng)用程序應(yīng)該可以在(幾乎)任何瀏覽器中運(yùn)行.
Should I use 'text/plain' or 'application/json', or perhaps 'multipart/x0mixed-replace' for this? Note: this app should work in (alomst) any browser.
如何處理僅在收到完整響應(yīng)后才調(diào)用 onReadyStateChange 的網(wǎng)絡(luò)瀏覽器(JavaScript 引擎)(所以我看不到 xhr.readyState == 3
即部分響應(yīng)不止一次)?好吧,除了使用一些 JavaScript 框架.
How to deal with web browser (JavaScript engines) which invoke onReadyStateChange only after receiving complete response (so I don't see xhr.readyState == 3
i.e. partial response more than once)? Well, beside using some JavaScript framework.
如何處理不完整的響應(yīng)(在這種情況下意味著不完整的行).
How to deal with incomplete responses (which in this situation mean incomplete lines).
我應(yīng)該發(fā)送響應(yīng)結(jié)束標(biāo)記,還是依靠計(jì)數(shù)器來檢查我們是否收到了所有數(shù)據(jù),或者我可以簡單地依靠檢測(cè) xhr.readyState == 4
?
Should I send end of response marker, or rely on counter to check if we received all data, or can I simply rely on detecting xhr.readyState == 4
?
即使是部分回應(yīng)也會(huì)有所幫助.
Even partial response would be helpful.
推薦答案
我認(rèn)為 Comet 是您的解決方案所需的一部分.您還可以(如果我沒記錯(cuò)的話)簽出 Bayeux Protocol,它是由 Dojo 基金會(huì)實(shí)施.整個(gè)事情還是很新的(盡管其中一些可能在第一個(gè) HTML5 實(shí)現(xiàn)中是可能的).
I think Comet is part of what you need for your solution. You can additionally (if I got that right) checkout the Bayeux Protocol which was implemented by the Dojo Foundation. The whole thing is still very new (though some of it might be possible with the first HTML5 implementations).
除此之外,您可能還必須實(shí)施輪詢方法.另一個(gè)問題是,客戶端 JavaScript 解釋器可以處理多少數(shù)據(jù).您是否有可能以某種方式分頁"您的數(shù)據(jù),這樣您就不會(huì)遇到請(qǐng)求處理仍在處理而另一個(gè)響應(yīng)已經(jīng)到來的問題?
Besides that you would probably have to implement the polling approach. The other question is, how much data the client side JavaScript interpreter can handle. Is there any possibility for you to somehow "page" your data so that you won't have the problem of request handling still processing while aother response comes in already?
這篇關(guān)于在 AJAX 中處理增量服務(wù)器響應(yīng)(在 JavaScript 中)的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!