首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
ASP | ASP.NET | JSP | PHP | AJAX | XML | Java script | HTML/CSS | 服务器类
各大城市软件开发培训、软件人才免费咨询热线:400-700-5807
 您现在的位置: 中国IT实验室 >> WEB开发 >> AJAX学习教程 >> 正文
错误分析和AJAX(XMLHttpRequest)
ChinaItLab  2005-8-29  保存本文    收藏本站


  即使你现在还没有听说,AJAX已经成为web技术领域最热门的词(就象Adaptive Path上的一篇文章提到的一样)。AJAX框架的关键是名为XMLHttpRequest的JavaScript对象,通过它客户端开发人员可以在不打断用户操作或者在充分使用隐藏表单的情况下通过HTTP直接发送和接收XML文档。现在,有些人可能会有这种忧虑,让那些以前只做表单(form)校验和增加图片动画效果的客户端开发人员突然间负责分析XML文档结构,以及与HTTP协议的header部分打交道,这能行吗?但是,没有风险就没有回报。为了减轻这种疑惑,我将展示如何使用XMLHttpRequest实现以前无法实现功能,同时如何减少程序错误和如何提高程序质量。
  
  XMLHttpRequest和XML DOM的JavaScript基础
  
  首先,我们需要声明一些规则。现在常用的浏览器(IE, Mozilla, Safari, Opera)都特别提供了对XMLHttpRequest对象的支持,同时也广泛支持XML DOM,虽然和往常一样:微软(Microsoft)使用了一种稍微有些不同的实现并有一些需要特殊注意的地方。和我们那些更进取的朋友直接实现XMLHttpRequest不同,IE需要你创建一个具有相同属性的ActiveXObject对象的实例。Apple Developer Connection网站上有一篇非常好的文章总览了XMLHttpRequest,并列举了它的全部特性。
  
  下面是个基础的例子:
  
  var req;function postXML(xmlDoc) {if (window.XMLHttpRequest) req = new XMLHttpRequest();
  else if (window.ActiveXObject) req = new ActiveXObject("Microsoft.XMLHTTP");
  else return;
  // fall on our swordreq.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 {// fall on our sword}}
  
  这个强大的工具应用前景非常广泛,而且对其潜在应用方面的探索才刚刚开始。但是在任何准备在网上建立XML园地的人失控前,我建议我们先架起一个安全网以防止任何抱负极高的人摔断他们的脖子。
  
  JavaScript错误处理基础
  
  JavaScript在其早期版本就支持简单的错误处理,但是非常简陋,只有少数的特性,并且实现的很差。新近的浏览器不仅支持了类似于C++和Java用于错误处理的关键字try/catch/finally,而且实现了onerror事件提供捕捉在运行期产生的任何错误。其使用方法非常简单而且直接:
  
  function riskyBusiness() {try {riskyOperation1();
  riskyOperation2();
  } catch (e) {// e是错误类型对象// 至少有两个属性:name及message} finally {// 清理工作}}window.onerror = handleError;
  // 架起捕获错误的安全网function handleError(message, URI, line) {// 提示用户,该页可能不能正确回应return true;
  // 这将终止默认信息}
  
  一个实例:将客户端的错误传递个服务器
  
  现在我们已经了解了XMLHttpRequest和JavaScript错误处理的基础,让我们通过一个简单的例子来看一下如何将这两个联系在一起使用。你也许会认为JavaScript错误应该很容易通过状态栏的黄色三角认出,但是我仍然在几个可靠组织的面向公众的网站上发现他们躲过了质量评估部门。
  
  因此,在这我将提供一种捕捉错误并将他们在服务器上记录,希望能够提醒某个人去修改这些错误。首先,我们考虑客户端。客户端需要提供一个产生日志记录的类,这个类在使用时必须只实例化一次,并能够透明地处理那些复杂的细节。
  
  我们首先创建构造器:
  
  // 一个类构造方法function Logger() {// 域this.req;
  // 方法this.errorToXML = errorToXML;
  this.log = log;}
  
  其次,我们定义一个将Error对象转成XML的方法。默认情况下,Error对象只有两个属性:name和message,但我们需要核对第三个可能很有用属性location。
  
  // 将一个错误映射到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方法。这是这段脚本将上述两个原则(XMLHttpRequest和XML DOM)结合在一起的最基础部分。注意我们使用了POST方法。在这我本质上是创建了一个只写的定制的web服务,在每一次成功的请求时它会建立一些新纪录。因此,使用POST是唯一可行的方法。
  
  // Logger类的日记方法function log(err) {// 嗅探环境if (window.XMLHttpRequest) this.req = new XMLHttpRequest();else if (window.ActiveXObject) this.req =new ActiveXObject("Microsoft.XMLHTTP");
  else return; // 无功而返// 确定方式及URIthis.req.open("POST", "/cgi-bin/AjaxLogger.cgi");
  // 设定request的headers。 如果错误出现在一个所包含的.js文件中,//REFERER 这个最顶层的URI可能会与产生错误的地方不一致this.req.setRequestHeader('REFERER', location.href);
  this.req.setRequestHeader('content-type', 'text/xml');
  // 请求完毕时要调用的函数this.req.onreadystatechange = errorLogged;
  this.req.send(this.errorToXML(err));
  // 如果不能在10秒在完成请求,// 需事务处理this.timeout = window.setTimeout("abortLog();", 10000);}
  
  最后是实例化日志记录类。注意这个类只能有一个实例。
  // logger只能有一个实例var logger = new Logger();
  
  最后还有两个我们的类里调用的方法。如果在记录错误时发生错误,除了告诉用户我们没有其它的办法。如果运气好的话,这种情况并不会出现。因为浏览器的事件(event)不会拥有我们的对象的引用,但是会引用我们创建的logger实例,所以这两个方法不是日志记录类的方法。
  
  // 尽管已经尝试,但如果有连接错误,放弃吧function abortLog() {logger.req.abort();
  alert("Attempt to log the error timed out.");}// 当request状态有变化则调用function errorLogged() {if (logger.req.readyState != 4) return;window.clearTimeout(logger.timeout);
  // 请求完毕if (logger.req.status >= 400)alert('Attempt to log the error failed.');}
  
  以上所有的代码都可以写在一个.js文件里,你可以在任何一个(或者所有)的页面里引入这个文件。下面是这个例子展示了如何引入并使用这个文件:
  
  <script type="text/javascript" src="Logger.js">
  </script>
  <script type="text/javascript">
  function trapError(msg, URI, ln) {
  // 将未知错误包装进一个对象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>
  
  现在我们已经知道如何将日志和HTML页面整合,剩下的就是如何接收和解析客户端传递到服务器的消息。我使用了大家易接受的CGI脚本来实现这个功能,在这个脚本里我用了XML::Simple(我最喜欢的模块之一)来解析提交上来的数据,并且用CGI::Carp将结果直接写到httpd(http服务程序)的错误日志里,这样你的系统管理员就不用去监控另一个日志。这个脚本里还包含了一些好的例子来说明如何对不同的成功和失败条件编写对应的响应代码。
  
  use CGI;use CGI::Carp qw(set_progname);use XML::Simple;
  my $request = CGI->new();my $method = $request->request_method();
  # method must be POSTif ($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";
  }
  # when method is POST and the content type is neither
  # URI encoded nor multipart form, the entire post
  # is stuffed into one param: 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'}));
  # this will change the name of the carper in the log
  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',<
中国IT教育热线咨询
相关文章
源代码解析——初探 AjaxTags
最新文章
·PHP正则表达式从url中取得域名
·php设计模式介绍之迭代器模式
·简单学习php遇到的主要问题
·asp根据表单自动生成sql语句的函
·雅虎选项卡特效
 文章评论

 精彩友情推荐
·Asp源码 PHP源码
·CGI源码 JSP源码
·建站书籍教程
·服务器软件 .net源码
·建站工具软件
·IDC资讯大全
·机房品质万里行
·IDC托管必备知识
·全国IDC报价
·网站推广优化
ASP.NET ASP PHP JSP
·extjs ComboBox联动下拉菜单示例08-01
·漫谈.Net开发关于命名空间和目录划分07-31
·在Silverlight应用程序中操作Cookie07-28
·带附加条件的NewID()用法(downmoon)07-28
·对自定义路由进行单元测试07-28
·javascript实现yield07-28
·在ASP.NET中使用Google Maps07-28
·Sql Server2005 实现Oracle10g的hash表分区功07-28
·asp.net get set用法07-26
·Asp.net 控件开发—数据回传07-26
·接口vs. 的实体类07-26
·php设计模式介绍之迭代器模式08-02
·简单学习php遇到的主要问题08-02
·asp根据表单自动生成sql语句的函数08-02
·教你优化你的ASP程序03-07
·asp去除HTML标记的三个实用函数03-07
·ASP添加验证码的解决方法03-07
·ASP通用文章分页函数:非记录集分页03-07
·ASP教程基础:十天学会ASP第三天03-07
·ASP教程基础:十天学会ASP第二天03-07
·ASP教程基础:十天学会ASP第一天03-07
·能够生成google xml地图的asp源码03-06
·Linux系统下让PHP提高性能的工具APC05-06
·一个完整、安全的PHP用户登录系统11-14
·Apache+PHP+MySQL建立数据库驱动的动态网站08-24
·用SSH与PHP相连接 确保数据传输的安全性08-23
·PHP5手动最简安装方法08-03
·PHP程序加速探索之服务器负载测试07-11
·完全讲解PHP+MySQL的分页显示示例分析05-30
·用Suhosin加强PHP脚本语言安全性05-26
·初学入门 PHP 和 MySQL05-17
·传奇的诞生 PHP三位创始人简介05-10
·大型系统上PHP令人不爽的九大原因05-10
·ASP.NET和PHP、JSP究竟学哪个?07-30
·JAVA (Jsp)利用Google的Translate开发API07-29
·由Servlet获得FacesContext及ManagedBeans07-24
·用JOTM向Servlet中添加事务07-18
·用servlet生成验证码07-16
·JSP/Servlet伪静态网页实现07-08
·JSP和Servlet的关系浅谈06-15
·妙用异步Servlet扩展AJAX应用程序06-11
·servlet生成验证码图片06-02
·java.servlet.Filter的应用05-30
·Java程序员必看--扩展鼠标右键菜单功能05-13
  培训中心
人才交流中心 技术交流中心
  ITLab技术交流平台: