免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Ajax的錯(cuò)誤處理機(jī)制探討

英文原址:http://www.xml.com/pub/a/2005/05/11/ajax-error.html
當(dāng)前web技術(shù)中最熱門的詞語是什么?是AJAX。AJAX框架組件的核心是XMLHttpRequest JavaScript對象,它允許客戶端開發(fā)人員在不中斷用戶操作、不利用隱藏頁面的情況下,通過HTTP發(fā)送和接收XML文檔?,F(xiàn)在,有些人可能會(huì)感到恐懼,因?yàn)樗蝗辉试S那些可能過多地使用了驗(yàn)證窗體和動(dòng)畫圖像的客戶端開發(fā)人員負(fù)責(zé)傳遞XML文檔和處理HTTP頭信息,但是,沒有風(fēng)險(xiǎn)就沒有收益。我們不用害怕,我將演示如何使用XMLHttpRequest來添加一些以前不可能的、行不通的特性,它同時(shí)還減少了錯(cuò)誤,提高了產(chǎn)品質(zhì)量。


  JavaScript中的XMLHttpRequest和XML DOM

  首先,我們需要建立一些規(guī)則。特殊的XMLHttpRequest對象和一般的XML DOM都受到了最新的瀏覽器(IE、Mozilla、Safari、Opera)的廣泛支持,盡管在一般情況下,微軟對于自己的實(shí)現(xiàn)會(huì)稍微增加一些東西,需要某些特殊的處理。盡管我們更多的朋友直接實(shí)現(xiàn)了XMLHttpRequest,但是IE還是要求你用相同的屬性實(shí)例化一個(gè)ActiveXObject。在Apple開發(fā)者關(guān)系站點(diǎn)上可以找到相關(guān)的概述和所有特性列表。

  下面是一個(gè)基本的例子:

var req;
function postXML(xmlDoc) {
 if (window.XMLHttpRequest) req = new XMLHttpRequest();
 else if (window.ActiveXObject) req = new ActiveXObject("Microsoft.XMLHTTP");
 else return; // 失敗了
 req.open(method, serverURI);
 req.setRequestHeader(’content-type’, ’text/xml’);
 req.onreadystatechange = xmlPosted;
 req.send(xmlDoc);
}
function xmlPosted() {
 if (req.readyState != 4) return;
 if (req.status == 200) {
  var result = req.responseXML;
 } else {
  // 失敗了
 }
}

  這種強(qiáng)大的功能的潛在用戶是很多的,對于它可能實(shí)現(xiàn)的功能的探索才剛剛開始。但是在你試圖在web上的建立XML功能之前,我建議你設(shè)置一個(gè)"安全網(wǎng)"來保證你的抱負(fù)(想法)不會(huì)受到打擊。

  JavaScript錯(cuò)誤處理基礎(chǔ)

  JavaScript已經(jīng)出現(xiàn)很久了,它的早期版本比較原始,缺少特性,僅僅是實(shí)現(xiàn)了而已。最新的瀏覽器不但支持C++和Java中try/catch/finally關(guān)鍵字,而且實(shí)現(xiàn)了onerror事件,而這個(gè)事件可以捕捉運(yùn)行時(shí)出現(xiàn)的任何錯(cuò)誤。它的使用是非常直接的:

function riskyBusiness() {
 try {
  riskyOperation1();
  riskyOperation2();
 } catch (e) {
  // e是一個(gè)Error類型的對象,至少有兩個(gè)屬性:name和message
 } finally {
  // 清除消息
 }
}
window.onerror = handleError; // 捕捉所有錯(cuò)誤的安全網(wǎng)
function handleError(message, URI, line) {
 // 提示用戶這個(gè)頁面可能無法正常響應(yīng)
 return true; // 停止默認(rèn)的消息
}

實(shí)際的例子:把客戶端錯(cuò)誤傳遞到服務(wù)器上

  現(xiàn)在我們知道了XMLHttpRequest和JavaScript錯(cuò)誤處理的一些基礎(chǔ)知識(shí)了,我們來看一個(gè)同時(shí)使用了兩者的實(shí)現(xiàn)例子。你可能認(rèn)為JavaScript錯(cuò)誤可以很簡單地在流行的"黃色死亡三角"中顯示出來,但是仍然有一些錯(cuò)誤傳遞到了幾家籃籌股公司的公共web站點(diǎn)的質(zhì)量部門了。

  因此,我將提供一個(gè)用于捕捉錯(cuò)誤并把錯(cuò)誤記錄到服務(wù)器上的方法,這樣其他人就可能修補(bǔ)這些問題。首先,我們考慮客戶端。客戶端必須提供一個(gè)類,它被用作日志記錄器(Logger)對象,可以透明地處理各種細(xì)節(jié)信息。

  下面是我們建立的構(gòu)造函數(shù):

// 類的構(gòu)造函數(shù)
function Logger() {
 // 字段
 this.req;

 // 方法
 this.errorToXML = errorToXML;
 this.log = log;
}

  接下來,我們定義了一個(gè)方法,它會(huì)把Error對象序列化為XML。在默認(rèn)情況下,Error對象只有兩種屬性,分別是name和message,但是我們還是使用了第三個(gè)屬性(location),它有時(shí)候是有用的。

// 把錯(cuò)誤映射到XML文檔中
function errorToXML(err) {
 var xml = ’<?xml version="1.0"?>\n’ +
 ’<error>\n’ +
 ’<name>’ + err.name + ’</name>\n’ +
 ’<message>’ + err.message + ’</message>\n’;
 if (err.location) xml += ’<location>’ + err.location +’</location>’;
  xml += ’</error>’;
 return xml;
}

  接著是log方法。這是腳本最基本的部分,它真正地實(shí)現(xiàn)了上述的原理。請注意,我們在調(diào)用中使用的是POST方法。從本質(zhì)上說,我在此處建立的是一個(gè)定制的web服務(wù),它是只讀的,并為每個(gè)成功的請求建立新記錄。因此,POST是唯一適當(dāng)?shù)倪x擇。

// 日志記錄類的log方法
function log(err) {
 // 查看特性
 if (window.XMLHttpRequest) this.req = new XMLHttpRequest();
 else if (window.ActiveXObject) this.req =new ActiveXObject("Microsoft.XMLHTTP");
 else return; // 失敗了
 // 設(shè)置方法和URI
 this.req.open("POST", "/cgi-bin/AjaxLogger.cgi");
 // 設(shè)置請求頭信息。REFERER 是頂層URI,如果它發(fā)生在一個(gè)包含的.js文件中
 // 那么它的位置與錯(cuò)誤的位置可能不同
 this.req.setRequestHeader(’REFERER’, location.href);
 this.req.setRequestHeader(’content-type’, ’text/xml’);
 // 請求完成的時(shí)候調(diào)用的函數(shù)
 this.req.onreadystatechange = errorLogged;
 this.req.send(this.errorToXML(err));
 // 如果請求在10秒鐘內(nèi)沒有完成,就出現(xiàn)一些錯(cuò)誤消息
 this.timeout = window.setTimeout("abortLog();", 10000);
}

  類的最后一部分建立了一個(gè)Logger類實(shí)例。這個(gè)類應(yīng)該只有一個(gè)實(shí)例。

// 只有一個(gè)日志記錄器實(shí)例
var logger = new Logger();

  最后的兩個(gè)函數(shù)只是用于瑣碎事務(wù)管理的。如果在記錄錯(cuò)誤的時(shí)候出現(xiàn)了問題,除了干擾用戶之外,我們幾乎不能做任務(wù)事務(wù)。但是,這種情況永遠(yuǎn)不會(huì)出現(xiàn)。這些不是類的方法,因?yàn)槭录]有指向我們的對象的指針,但是它會(huì)指向我們建立的logger實(shí)例。

// 我們試過了,但是連接錯(cuò)誤,沒有希望了
function abortLog() {
 logger.req.abort();
 alert("Attempt to log the error timed out.");
}

// 請求的狀態(tài)發(fā)生改變的時(shí)候調(diào)用
function errorLogged() {
 if (logger.req.readyState != 4) return;
 window.clearTimeout(logger.timeout);
 // 請求完成了
 if (logger.req.status >= 400)
  alert(’Attempt to log the error failed.’);
}

  前面的所有代碼都被包裝到一個(gè).js文件中了,我們可以在站點(diǎn)的任何(或每一個(gè))頁面中包含這個(gè)文件。下面是如何包含這個(gè)文件的例子:

<script type="text/javascript" src="Logger.js"></script>
<script type="text/javascript">
function trapError(msg, URI, ln) {
 // 在對象中包裝我們未知的錯(cuò)誤
 var error = new Error(msg);
 error.location = URI + ’, line: ’ + ln; // 添加自定義屬性
 logger.log(error);
 warnUser();
 return true; // 停止黃色三角形
}
window.onerror = trapError;

function foo() {
 try {
  riskyOperation();
 } catch (err) {
  //添加自定義屬性
  err.location = location.href + ’, function: foo()’;
  logger.log(err);
  warnUser();
 }
}
function warnUser() {
 alert("An error has occurred while processing this page."+"Our engineers have been alerted!");
 location.href = ’/path/to/error/page.html’;
}
</script>

  現(xiàn)在你已經(jīng)知道如何把日志記錄器集成到HTML頁面中了,剩余的工作就是定義一種接收和轉(zhuǎn)換消息的方法了。我選擇使用最底層的通用命名方法,在Perl中建立了一個(gè)CGI腳本,這個(gè)腳本使用了我喜歡的一些模塊,它使用XML::Simple來分析post數(shù)據(jù),使用CGI::Carp把結(jié)果直接導(dǎo)入到httpd錯(cuò)誤日志,這樣可以節(jié)約系統(tǒng)管理員的時(shí)間,因?yàn)樗恍枰榭戳硗庖粋€(gè)日志了。這個(gè)腳本還包含了很多良好的示例,它們適當(dāng)?shù)赜涗浟瞬煌某晒褪l件。

use CGI;
use CGI::Carp qw(set_progname);
use XML::Simple;
my $request = CGI->new();

my $method = $request->request_method();
# 方法必須是POST
if ($method eq ’POST’) {
 eval {
  my $content_type = $request->content_type();
  if ($content_type eq ’text/xml’) {
   print $request->header(-status =>’415 Unsupported Media Type’, -type => ’text/xml’);
   croak "Invalid content type: $content_type\n";
  }
  # 如果方法是POST,內(nèi)容既不是URL編碼也不是多部分形式,
  #那么整個(gè)post會(huì)被填充到一個(gè)參數(shù)中:POSTDATA。
  my $error_xml = $request->param(’POSTDATA’);
  my $ref = XML::Simple::XMLin($error_xml);
  my ($name, $msg, $location) =($ref->{’name’}, $ref->{’message’}, ’’);
  $location = $ref->{’location’} if (defined($ref->{’location’}));
  # 改變?nèi)罩局械拿?br>  set_progname(’Client-side error’);
  my $remote_host = $request->remote_host();
  carp "name: [$name], msg: [$msg], location: [$location]";
 };
 if ($@) {
  print $request->header(-status => ’500 Internal server error’,-type => ’text/xml’);
  croak "Error while logging: $@";
 } else {
  # 這部分響應(yīng)代碼表明操作成功了,但是客戶端不應(yīng)該期待任何內(nèi)容
  print $request->header(-status => ’204 No content’,-type => ’text/xml’);
 }
 } else {
  print $request->header(-status => ’405 Method not supported’,-type => ’text/xml’);
  croak "Unsupported method: $method";
}

  已經(jīng)完成了!現(xiàn)在,當(dāng)某些難以理解的JavaScript進(jìn)入系統(tǒng)的時(shí)候,你就可以期待著自己的日志監(jiān)視器開始閃紅燈,你的客戶端開發(fā)人員在深夜接到電話了。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Ajax
AJAX原理
用ref的屬性指定依賴的3種模式
石鍋拌飯 JSON
掌握 ajax,第 1 部分: ajax 簡介
面向Java開發(fā)人員的Ajax技術(shù)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服