`
longgangbai
  • 浏览: 7250174 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Prototype的源码分析

阅读更多

/*
*这个文件是对xmlhttp异步请求进行了简单的封装,
*主要是将prototytp进行了简化,如果要使用复杂的功能可以使用prototype的ajax.js
*外部使用时,主要调用方式为
* var myAjax=new Ajax.Request(
    url,
    {
    method: 'get',
    asynchronous: true,
    onSuccess: function(xmlHttp)
    {       
    },
    onFailure:function(xmlHttp){
    },
    onException:function(exception){
    }
    }
   );
   另可使用myAjax.header()和myAjax.evalResponse();
   其他的都为内部调用函数,外部尽量不要使用。
*/

/*
*基础函数
*Class.create()
*Try.these()
*Object.extend()
*Function.prototype.bind
*/
var Class = {
   create: function() {
     return function() {
       this.initialize.apply(this, arguments);
     }
   }
};
var Try = {
   these: function() {
     var returnValue;

     for (var i = 0; i < arguments.length; i++) {
       var lambda = arguments[i];
       try {
         returnValue = lambda();
         break;
       } catch (e) {}
     }

     return returnValue;
   }
};
var Abstract = new Object();
Object.extend = function(destination, source) {
   for (property in source) {
     destination[property] = source[property];
   }
   return destination;
};
Function.prototype.bind = function(object) {
   var __method = this;
   return function() {
     __method.apply(object, arguments);
   }
};
/*
*基础ajax类
*封装了一个函数:Ajax.getTransport()返回一个xmlhttp对象
*这个类里的函数一般不使用。
*/
var Ajax = {
     getTransport: function() {
         return Try.these(
             function() {return new ActiveXObject('Msxml2.XMLHTTP')},
             function() {return new ActiveXObject('Microsoft.XMLHTTP')},
             function() {return new XMLHttpRequest()}
         ) || false;
     }
};
/*
*基础ajax.base类
*封装了三个函数:
*setOptions:设置进行ajax请求的参数
*responseIsSuccess:判断异步请求返回是否成功
*responseIsFailure:判断异步请求返回是否失败
*这个类里的函数也没有必要在实际中使用,只有在扩展是才会使用到
*/
Ajax.Base = function() {};
Ajax.Base.prototype = {
   setOptions: function(options) {
     this.options = {
       method:        'post',//异步请求方法,可以为get和post
       asynchronous: true,   //设置是否为异步方式发送,
       parameters:    ''      //传递参数,参数都是url编码格式a=valueOfA&b=valueOfB
     }
     Object.extend(this.options, options || {});//以上三个属性为异步请求的基本属性。
   },
   responseIsSuccess: function() {
     return this.transport.status == undefined
         || this.transport.status == 0
         || (this.transport.status >= 200 && this.transport.status < 300);
   },
   responseIsFailure: function() {
     return !this.responseIsSuccess();
   }
};

Ajax.Request = Class.create();
/*
*定义了xmlhttp请求的状态。
*0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)
*1 (初始化) 对象已建立,尚未调用send方法
*2 (发送数据) send方法已调用,但是当前的状态及http头未知
*3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误,
*4 (完成) 数据接收完毕,此时可以通过通过responseBody和responseText获取完整的回应数据
*/
Ajax.Request.Events =   ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
/*
*Ajax.Request对象,需要实例化对象,
*
*/
Ajax.Request.prototype = Object.extend(new Ajax.Base(),{
   initialize: function(url, options) {
     this.transport = Ajax.getTransport();//返回xmlhttp对象
this.setOptions(options);//设置请求的参数,在初始化时写
     this.request(url);//进行异步请求
   },
   request: function(url) {
     var parameters = this.options.parameters || '';
     if (parameters.length > 0) parameters += '&_=';

     try {
       this.url = url;
    /*如果是get方法的化,就将parameters里的内容添加到url里*/
       if (this.options.method == 'get' && parameters.length > 0)
         this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
       /*调用xmlhttp的请求函数,进行请求*/
       this.transport.open(this.options.method, this.url,
     this.options.asynchronous);

       /*如果是异步请求,对onreadystatechange绑定函数,对于为什么要用定时器,没10ms将状态设为Loading,我也没有明白。*/
    if (this.options.asynchronous) {
         this.transport.onreadystatechange = this.onStateChange.bind(this);
         setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
       }

   this.setRequestHeaders();//设置请求里的头部信息,包括编码等信息

    /*对与post方式请求,也可以通过options里的postBody来设,这里就将postbody放到参数里进行传递*/
       var body = this.options.postBody ? this.options.postBody : parameters;
    /*发送post数据*/
       this.transport.send(this.options.method == 'post' ? body : null);

     } catch (e) {
       this.dispatchException(e);
     }
    },
setRequestHeaders: function() {
     var requestHeaders =   ['X-Requested-With', 'XMLHttpRequest'];

     if (this.options.method == 'post') {
       requestHeaders.push('Content-type',
         'application/x-www-form-urlencoded');

       /* Force "Connection: close" for Mozilla browsers to work around
        * a bug where XMLHttpReqeuest sends an incorrect Content-length
        * header. See Mozilla Bugzilla #246651.
        */
       if (this.transport.overrideMimeType)
         requestHeaders.push('Connection', 'close');
     }

     if (this.options.requestHeaders)
       requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);

     for (var i = 0; i < requestHeaders.length; i += 2)
       this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
   },
/*
*状态改变时,执行respondToReadyState,判断当状态为1时不执行。
*/
   onStateChange: function() {
     var readyState = this.transport.readyState;
     if (readyState != 1)
       this.respondToReadyState(this.transport.readyState);
   },
/*
   *返回异步请求返回文件的头部信息,name表示名字,函数返回参数值
   */
   header: function(name) {
     try {
       return this.transport.getResponseHeader(name);
     } catch (e) {}
   },
   /*
   *如果返回header信息里包括X-JSON/xxx,则会执行xxx的内容
   *不是很明白这里,为什么要eval
   */
   evalJSON: function() {
     try {
       return eval(this.header('X-JSON'));
     } catch (e) {}
   },
   /*
   *很简单的函数,如果返回Content-type为text/javascript,则会调用此函数进行执行,我认为这处用途不大
   */
   evalResponse: function() {
     try {
       return eval(this.transport.responseText);
     } catch (e) {
       this.dispatchException(e);
     }
   },
/*
   *根据返回的状态决定该执行的步骤
   */
   respondToReadyState: function(readyState) {
     var event = Ajax.Request.Events[readyState];
     var transport = this.transport, json = this.evalJSON();

     if (event == 'Complete') {
   /*
   *此处如果状态处于完成状态则会进行分析分别调用onSuccess和onFailure,所以一般onComplete不调用为好
   */
       try {
         (this.options['on' + this.transport.status]
          || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
          || function(){})(transport, json);
       } catch (e) {
         this.dispatchException(e);
       }
       /*此处对返回js进行了eval*/
       if ((this.header('Content-type') || '').match(/^text\/javascript/i))
         this.evalResponse();
     }
    
     try {
       (this.options['on' + event] || function(){})(transport, json);
     } catch (e) {
       this.dispatchException(e);
     }
    
     /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
     if (event == 'Complete')
       this.transport.onreadystatechange = function(){};
   },
   /*
   *错误时调用,一般外部使用onException:function(){}
   */
   dispatchException: function(exception) {
     (this.options.onException || function(){})(this, exception);
   }

   }
);

分享到:
评论

相关推荐

    使用Prototype框架.pdfprototype源码分析.doc

    例解Prototype框架.doc 第21章__使用Prototype框架.pdf Prototype源码注释版.pdf proprototype源码分析.doc totype_1.3_源码解读.txt

    prototype源码下载

    prototype源码下载,没有压缩过,请各位看官下载分析理解

    [pdf]Jquery1.2.6源码分析

    jQuery 是一个非常优秀的 JS 库,与 Prototype,YUI,Mootools 等众多的 Js 类 库相比,它剑走偏锋,从web开发的...这就是本源码分析的原因,让所有使用 jQuery 的读者,能快速 上手 jQuery的源码,并在开发中得心应用。

    Jquery1.2.6 源码分析

    这就是本源码分析的原因,让所有使用jQuery的读者,能快速上手jQuery的源码,并在开发中得心应用。 Jquery的网络资源丰富,但Baidu了很久,很难找到那种完全深入地分析Jquery源码的文稿。倒是Jquery的开发者,John ...

    Jquery1.2.6源码分析教程

    Jquery1.2.6源码分析教程,这是一个非常优秀的JS库,与PROTOTYPE,YUI,MOOTOOLS相比,性能高效。 勾月科技www.gouyue.net QQ17878387

    jquery api, jquery ui api, jquery源码分析

    Jquery是继prototype之后又一个优秀的Javascrīpt框架

    myjquery:jquery源码分析

    jQuery源码分析 前言 有时候我在想jQuery为什么可以直接$操作,可以拥有比原生js更便利的DOM操作,而且只要你想就可以直接链式操作下去 核心框架 揭开一万多行代码的jQuery核心代码: (function(window, undefined)...

    Jquery1.2.6源码分析

    jQuery是一个非常优秀的JS库,与Prototype,YUI,Mootools等众多的Js类库相比,它剑走偏锋,从web开发的实用角度出发,抛除了其它Lib中一些中看但不实用的东西,为开发者提供了优美短小而精悍的类库。其使用简单,文档...

    Prototype源码浅析 String部分(一)之有关indexOf优化

    添加到String.prototype中的方法比较多,不过归结起来,大致分为下面几类: 分类 方法名  原始能力增强 strip | include | startsWith | endsWith | empty | blank 格式 camelize | capitalize | ...

    Prototype源码浅析 Number部分

    Prototype在原生对象的基础上扩展,分别是Object,Function,String,Number,Array,Date,前面分析了Object,Function,String,还剩下Number,Array,Date

    jQuery.prototype.init选择器构造函数源码思路分析

    一、源码思路分析总结 概要: jQuery的核心思想可以简单概括为“查询和操作dom”,今天主要是分析一下jQuery.prototype.init选择器构造函数,处理选择器函数中的参数; 这个函数的参数就是jQuery()===$()执行函数中...

    Vue源码中要const _toStr = Object.prototype.toString的原因分析

    主要介绍了Vue源码中要const _toStr = Object.prototype.toString的原因分析,在文中给大家提到了Object.prototype.toString方法的原理,需要的朋友可以参考下

    jQuery源码分析之Event事件分析

    对于javascript事件扩展,所有的lib都差不多。和jquery和prototype,yui和Ext,其要解决的首要问题是兼容性,所有 lib都会对event进行包裹,统一其属性解决其兼容性。

    由浅入深讲解Javascript继承机制与simple-inheritance源码分析

    老生常谈的问题,大部分人也不一定可以系统的理解。Javascript语言对继承实现的并不好,需要工程师自己去...SuperType.prototype.getSuperValue = function(){ return this.property; } function SubType(){ this.sub

    Spring 循环引用(三)源码深入分析版

    循环引用源码分析前言正文分析doGetBean为什么Prototype不可以createBeandoCreateBeangetEarlyBeanReferencegetSingletonbeforeSingletonCreationsingletonFactory....前言 关于Spring 循环引用 网上的分析文章很多,写...

    发送邮件(sendmail)的源代码

    SendMail.h This is the main header file for the application. It includes other project specific headers (including Resource.h) and declares the ... maps and to create prototype member functions.

    经典:WEB开发必备参考资料

    XMLHTTP 手册.CHM 正则表达式系统教程.CHM ...prototype.chm XMLDOM对象手册.chm DHTML默认行为手册.chm 设计模式手册.chm DOM文档对象模型手册.chm SQL参考手册.chm 网页设计配色常识.chm ...Jquery1.2.6源码分析.pdf

Global site tag (gtag.js) - Google Analytics