一份老外写的XMLHttpRequest代码多浏览器支持兼容性


Posted in Javascript onJanuary 11, 2007

这几天要构思用Javascript调用Asp.Net的WebService,需要到XMLHTTP来支持,但发现Opera的XMLHttpRequest很烂,实在支持不下去,后来到处找,终于发现这份代码,在Opera中是利用java.net.URL等类来实现的,不敢独享,特发上来与大家同乐。

/* Cross-Browser XMLHttpRequest v1.2 
================================= 
Emulate Gecko 'XMLHttpRequest()' functionality in IE and Opera. Opera requires 
the Sun Java Runtime Environment <http://www.java.com/>. 
by Andrew Gregory 
http://www.scss.com.au/family/andrew/webdesign/xmlhttprequest/ 
This work is licensed under the Creative Commons Attribution License. To view a 
copy of this license, visit http://creativecommons.org/licenses/by-sa/2.5/ or 
send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 
94305, USA. 
Attribution: Leave my name and web address in this script intact. 
Not Supported in Opera 
---------------------- 
* user/password authentication 
* responseXML data member 
Not Fully Supported in Opera 
---------------------------- 
* async requests 
* abort() 
* getAllResponseHeaders(), getAllResponseHeader(header) 
*/ 
// IE support 
if (window.ActiveXObject && !window.XMLHttpRequest) { 
  window.XMLHttpRequest = function() { 
    var msxmls = new Array( 
      'Msxml2.XMLHTTP.5.0', 
      'Msxml2.XMLHTTP.4.0', 
      'Msxml2.XMLHTTP.3.0', 
      'Msxml2.XMLHTTP', 
      'Microsoft.XMLHTTP'); 
    for (var i = 0; i < msxmls.length; i++) { 
      try { 
        return new ActiveXObject(msxmls[i]); 
      } catch (e) { 
      } 
    } 
    return null; 
  }; 
} 
// Gecko support 
/* ;-) */ 
// Opera support 
if (window.opera && !window.XMLHttpRequest) { 
  window.XMLHttpRequest = function() { 
    this.readyState = 0; // 0=uninitialized,1=loading,2=loaded,3=interactive,4=complete 
    this.status = 0; // HTTP status codes 
    this.statusText = ''; 
    this._headers = []; 
    this._aborted = false; 
    this._async = true; 
    this._defaultCharset = 'ISO-8859-1'; 
    this._getCharset = function() { 
      var charset = _defaultCharset; 
      var contentType = this.getResponseHeader('Content-type').toUpperCase(); 
      val = contentType.indexOf('CHARSET='); 
      if (val != -1) { 
        charset = contentType.substring(val); 
      } 
      val = charset.indexOf(';'); 
      if (val != -1) { 
        charset = charset.substring(0, val); 
      } 
      val = charset.indexOf(','); 
      if (val != -1) { 
        charset = charset.substring(0, val); 
      } 
      return charset; 
    }; 
    this.abort = function() { 
      this._aborted = true; 
    }; 
    this.getAllResponseHeaders = function() { 
      return this.getAllResponseHeader('*'); 
    }; 
    this.getAllResponseHeader = function(header) { 
      var ret = ''; 
      for (var i = 0; i < this._headers.length; i++) { 
        if (header == '*' || this._headers[i].h == header) { 
          ret += this._headers[i].h + ': ' + this._headers[i].v + '\n'; 
        } 
      } 
      return ret; 
    }; 
    this.getResponseHeader = function(header) { 
      var ret = getAllResponseHeader(header); 
      var i = ret.indexOf('\n'); 
      if (i != -1) { 
        ret = ret.substring(0, i); 
      } 
      return ret; 
    }; 
    this.setRequestHeader = function(header, value) { 
      this._headers[this._headers.length] = {h:header, v:value}; 
    }; 
    this.open = function(method, url, async, user, password) { 
      this.method = method; 
      this.url = url; 
      this._async = true; 
      this._aborted = false; 
      this._headers = []; 
      if (arguments.length >= 3) { 
        this._async = async; 
      } 
      if (arguments.length > 3) { 
        opera.postError('XMLHttpRequest.open() - user/password not supported'); 
      } 
      this.readyState = 1; 
      if (this.onreadystatechange) { 
        this.onreadystatechange(); 
      } 
    }; 
    this.send = function(data) { 
      if (!navigator.javaEnabled()) { 
        alert("XMLHttpRequest.send() - Java must be installed and enabled."); 
        return; 
      } 
      if (this._async) { 
        setTimeout(this._sendasync, 0, this, data); 
        // this is not really asynchronous and won't execute until the current 
        // execution context ends 
      } else { 
        this._sendsync(data); 
      } 
    } 
    this._sendasync = function(req, data) { 
      if (!req._aborted) { 
        req._sendsync(data); 
      } 
    }; 
    this._sendsync = function(data) { 
      this.readyState = 2; 
      if (this.onreadystatechange) { 
        this.onreadystatechange(); 
      } 
      // open connection 
      var url = new java.net.URL(new java.net.URL(window.location.href), this.url); 
      var conn = url.openConnection(); 
      for (var i = 0; i < this._headers.length; i++) { 
        conn.setRequestProperty(this._headers[i].h, this._headers[i].v); 
      } 
      this._headers = []; 
      if (this.method == 'POST') { 
        // POST data 
        conn.setDoOutput(true); 
        var wr = new java.io.OutputStreamWriter(conn.getOutputStream(), this._getCharset()); 
        wr.write(data); 
        wr.flush(); 
        wr.close(); 
      } 
      // read response headers 
      // NOTE: the getHeaderField() methods always return nulls for me :( 
      var gotContentEncoding = false; 
      var gotContentLength = false; 
      var gotContentType = false; 
      var gotDate = false; 
      var gotExpiration = false; 
      var gotLastModified = false; 
      for (var i = 0; ; i++) { 
        var hdrName = conn.getHeaderFieldKey(i); 
        var hdrValue = conn.getHeaderField(i); 
        if (hdrName == null && hdrValue == null) { 
          break; 
        } 
        if (hdrName != null) { 
          this._headers[this._headers.length] = {h:hdrName, v:hdrValue}; 
          switch (hdrName.toLowerCase()) { 
            case 'content-encoding': gotContentEncoding = true; break; 
            case 'content-length'  : gotContentLength   = true; break; 
            case 'content-type'    : gotContentType     = true; break; 
            case 'date'            : gotDate            = true; break; 
            case 'expires'         : gotExpiration      = true; break; 
            case 'last-modified'   : gotLastModified    = true; break; 
          } 
        } 
      } 
      // try to fill in any missing header information 
      var val; 
      val = conn.getContentEncoding(); 
      if (val != null && !gotContentEncoding) this._headers[this._headers.length] = {h:'Content-encoding', v:val}; 
      val = conn.getContentLength(); 
      if (val != -1 && !gotContentLength) this._headers[this._headers.length] = {h:'Content-length', v:val}; 
      val = conn.getContentType(); 
      if (val != null && !gotContentType) this._headers[this._headers.length] = {h:'Content-type', v:val}; 
      val = conn.getDate(); 
      if (val != 0 && !gotDate) this._headers[this._headers.length] = {h:'Date', v:(new Date(val)).toUTCString()}; 
      val = conn.getExpiration(); 
      if (val != 0 && !gotExpiration) this._headers[this._headers.length] = {h:'Expires', v:(new Date(val)).toUTCString()}; 
      val = conn.getLastModified(); 
      if (val != 0 && !gotLastModified) this._headers[this._headers.length] = {h:'Last-modified', v:(new Date(val)).toUTCString()}; 
      // read response data 
      var reqdata = ''; 
      var stream = conn.getInputStream(); 
      if (stream) { 
        var reader = new java.io.BufferedReader(new java.io.InputStreamReader(stream, this._getCharset())); 
        var line; 
        while ((line = reader.readLine()) != null) { 
          if (this.readyState == 2) { 
            this.readyState = 3; 
            if (this.onreadystatechange) { 
              this.onreadystatechange(); 
            } 
          } 
          reqdata += line + '\n'; 
        } 
        reader.close(); 
        this.status = 200; 
        this.statusText = 'OK'; 
        this.responseText = reqdata; 
        this.readyState = 4; 
        if (this.onreadystatechange) { 
          this.onreadystatechange(); 
        } 
        if (this.onload) { 
          this.onload(); 
        } 
      } else { 
        // error 
        this.status = 404; 
        this.statusText = 'Not Found'; 
        this.responseText = ''; 
        this.readyState = 4; 
        if (this.onreadystatechange) { 
          this.onreadystatechange(); 
        } 
        if (this.onerror) { 
          this.onerror(); 
        } 
      } 
    }; 
  }; 
} 
// ActiveXObject emulation 
if (!window.ActiveXObject && window.XMLHttpRequest) { 
  window.ActiveXObject = function(type) { 
    switch (type.toLowerCase()) { 
      case 'microsoft.xmlhttp': 
      case 'msxml2.xmlhttp': 
      case 'msxml2.xmlhttp.3.0': 
      case 'msxml2.xmlhttp.4.0': 
      case 'msxml2.xmlhttp.5.0': 
        return new XMLHttpRequest(); 
    } 
    return null; 
  }; 
}
Javascript 相关文章推荐
js String对象中常用方法小结(字符串操作)
Jan 27 Javascript
javascript如何判断输入的url是否正确
Apr 11 Javascript
jQuery购物网页经典制作案例
Aug 19 Javascript
详谈$.data()的用法和作用
Feb 13 Javascript
javascript数据结构中栈的应用之符号平衡问题
Apr 11 Javascript
浅谈JS如何实现真正的对象常量
Jun 25 Javascript
vue实现商城购物车功能
Nov 27 Javascript
vue实现验证码输入框组件
Dec 14 Javascript
js装饰设计模式学习心得
Feb 17 Javascript
微信小程序多音频播放进度条问题
Aug 28 Javascript
vue指令v-html使用过滤器filters功能实例
Oct 25 Javascript
OpenLayers3加载常用控件使用方法详解
Sep 25 Javascript
javascript基础的动画教程,直观易懂
Jan 10 #Javascript
JS宝典学习笔记(下)
Jan 10 #Javascript
js宝典学习笔记(上)
Jan 10 #Javascript
javascript编程起步(第七课)
Jan 10 #Javascript
javascript编程起步(第六课)
Jan 10 #Javascript
javascript编程起步(第五课)
Jan 10 #Javascript
javascript编程起步(第四课)
Jan 10 #Javascript
You might like
按上下级层次关系输出内容的PHP代码
2010/07/17 PHP
LotusPhp笔记之:Cookie组件的使用详解
2013/05/06 PHP
PHPStrom 新建FTP项目以及在线操作教程
2016/10/16 PHP
Extjs学习笔记之三 extjs form更多的表单项
2010/01/07 Javascript
javascript 数据类型转换(parseInt,parseFloat)
2010/07/20 Javascript
DWZ刷新dialog解决方法
2013/03/03 Javascript
js关闭当前页面(窗口)的几种方式总结
2013/03/05 Javascript
js获取下拉列表框中的value和text的值示例代码
2014/01/11 Javascript
Javascript动画的实现原理浅析
2015/03/02 Javascript
JS动态日期时间的获取方法
2015/09/28 Javascript
利用CSS3在Angular中实现动画
2016/01/15 Javascript
Node.js的Express框架使用上手指南
2016/03/12 Javascript
js自定义QQ菜单效果
2017/01/10 Javascript
AngularJS 异步解决实现方法
2017/06/12 Javascript
原生JavaScrpit中异步请求Ajax实现方法
2017/11/03 Javascript
Angular开发实践之服务端渲染
2018/03/29 Javascript
JavaScript解析JSON数据示例
2019/07/16 Javascript
[56:48]FNATIC vs EG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
python通过邮件服务器端口发送邮件的方法
2015/04/30 Python
简介Django中内置的一些中间件
2015/07/24 Python
python机器人运动范围问题的解答
2019/04/29 Python
对django的User模型和四种扩展/重写方法小结
2019/08/17 Python
django自带serializers序列化返回指定字段的方法
2019/08/21 Python
wxPython实现列表增删改查功能
2019/11/19 Python
使用Python的networkx绘制精美网络图教程
2019/11/21 Python
python和php哪个更适合写爬虫
2020/06/22 Python
Django视图、传参和forms验证操作
2020/07/15 Python
运动鞋、街头服装、手表和手袋的实时市场:StockX
2020/11/25 全球购物
估算杭州有多少软件工程师
2015/08/11 面试题
办加油卡单位介绍信
2014/01/09 职场文书
教堂婚礼主持词
2014/03/14 职场文书
单位消防安全责任书
2014/07/23 职场文书
意向书范本
2014/07/29 职场文书
汽车服务工程专业自荐信
2014/09/02 职场文书
2014年政风行风工作总结
2014/11/22 职场文书
2016春节家属慰问信
2015/03/25 职场文书