错误和AJAX

ajax|错误

  即使你现在还没有听说,AJAX已经成为web技术领域最热门的词。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 sword
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 {
// 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; // 无功而返
// 确定方式及URI
this.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文件里,你可以在任何一个(或者所有)的页面里引入这个文件。下面是这个例子展示了如何引入并使用这个文件:

  现在我们已经知道如何将日志和HTML页面整合,剩下的就是如何接收和解析客户端传递到服务器的消息。我使用了大家易接受的CGI脚本来实现这个功能,在这个脚本里我用了XML::Simple(我最喜欢的模块之一)来解析提交上来的数据,并且用CGI::Carp将结果直接写到httpd(http服务程序)的错误日志里,这样你的系统管理员就不用去监控另一个日志。这个脚本里还包含了一些好的例子来说明如何对不同的成功和失败条件编写对应的响应代码。

<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 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";
      }
      # 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',
         -type => 'text/xml');
      croak "Error while logging: $@";
   } else {
      # this response code indicates that the operation was a
      # success, but the client should not expect any content
      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";
}

  以上就是全部的代码了。现在,当下次有一些有问题的JavaScript代码溜进系统时,你可以想象你的日志监控人员开始闪动红色的灯,而你的客户端开发人员在半夜接到电话的情景。

时间: 2024-10-31 15:42:54

错误和AJAX的相关文章

Ajax的错误处理机制

ajax|错误|错误处理 AJAX框架组件的核心是XMLHttpRequest JavaScript对象,它允许客户端开发人员在不中断用户操作.不利用隐藏页面的情况下,通过HTTP发送和接收XML文档.现在,有些人可能会感到恐惧,因为它突然允许那些可能过多地使用了验证窗体和动画图像的客户端开发人员负责传递XML文档和处理HTTP头信息,但是,没有风险就没有收益.我们不用害怕,我将演示如何使用XMLHttpRequest来添加一些以前不可能的.行不通的特性,它同时还减少了错误,提高了产品质量. J

Ajax Hacks-hack8 处理Request Object 的错误

ajax|object|request|错误 Ajax Hacks-hack8 处理Request Object 的错误 让Ajax能检测服务器的错误,并能像用户提供有用的信息. Ajax技术的魅力在于允许JavaScript能在用户不干预的情况下与服务器连接.然而JavaScript开发者经常无法控制服务器组件(可能是一个web服务或其他软件).尽管你的应用程序包括了你自己的服务器组件,也无法保证服务器永远运行正常或者用户遇到错误.因此,当程序出错时候,必须保证应用产业程序能恢复. 本hack

ajax请求php一直执行error函数,数据库操作正常,错误500

问题描述 ajax请求php一直执行error函数,数据库操作正常,错误500 $.ajax({ type:""post"" url:""../php/insert_articles.php"" data:""title="" +tle +""&content="" + cnt +""&time="&q

完美解决ajax跨域请求下parsererror的错误

ajax请求报parsererror错误是很宽泛的概念,很多情况下都报这个错, 在很多时候,即使ajax提交.返回都正常 XMLHttpRequest.status=200  (正常响应) XMLHttpRequest.readyState=4 (正常接收) ajax也会提示一个parseerror的错误. 出现这个错误,大都是不良书写习惯,或者语法不当造成的. 关于ajax的错误,请使用: error:function(XMLHttpRequest, textStatus, errorThro

js错误处理与调试理论和办法

                                                                                                                                        阅读本文,以抓取有用的信息(可以以我加粗为参考)为主,老外写的 废话较多 ECMA-262 第 3 版引入了 try-catch 语句,作为 JavaScript 中处理异常的一种标准方式.基本的语 法如下所示,显而易见,这与

在BEA WEBLOGIC PORTAL中进行AJAX编程 第1部分

摘要 门户应用程序非常适用于从多个源提取信息以及为包含门户Web应用程序的portlet提供应用服务.对于用户,portlet应用程序是独立的实体,类似于桌面上的窗口应用程序.如果在一个窗口应用程序中执行一项操作会导致其他所有应用程序中的内容被刷新,那又会怎么样呢?这就是当前大多数门户的情况.在一个portlet中通过页面流进行转移会导致整个Web页面被刷新,包括该页面上的其他所有portlet. 为了避免出现这种有时不希望有的行为,Web开发人员采用了所谓Ajax-风格的编程方法.Ajax即异

AJAX对服务器返回XML的处理方法_AJAX相关

本文实例讲述了AJAX对服务器返回XML的处理方法.分享给大家供大家参考.具体分析如下: 在AJAX 中,服务器端如果返回的XML 文档,则可以通过异步对象的responseXML 属性来获取器XML 数据.而开发者可以利用DOM 的相关方法对其进行处理. 假设服务器返回的XML 文档,如下所示: <?xml version="1.0" encoding="gb2312"?> <list> <caption>Member List

简洁Ajax函数处理(示例代码)_jquery

以下是封装的一个处理函数,使用是也十分方便: 文件的名字命名为: jQuery.ajaxRequest.js . 使用方法: 复制代码 代码如下: $('._ajax').click(function(){ _ajax.request(this);  return false;  }); var _ajax = {      request: function(o){             var tform = $(o).parents('form');             _ar2(t

jQuery基础---Ajax进阶

原文:jQuery基础---Ajax进阶 内容提纲: 1.加载请求 2.错误处理 3.请求全局事件 4.JSON 和 JSONP 5.jqXHR 对象 发文不易,转载请注明出处!   在 Ajax 基础一篇中,我们了解了最基本的异步处理方式.本篇来了解一下 Ajax 的一些全局请求事件.跨域处理和其他一些问题. 一.加载请求 在 Ajax 异步发送请求时,遇到网速较慢的情况,就会出现请求时间较长的问题.而超过一定时间的请求, 用户就会变得不再耐烦而关闭页面. 而如果在请求期间能给用户一些提示,比