一份老外写的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 相关文章推荐
菜鸟javascript基础资料整理3 正则
Dec 06 Javascript
javascript:;与javascript:void(0)使用介绍
Jun 05 Javascript
Jquery操作radio的简单实例
Jan 06 Javascript
Node.js中require的工作原理浅析
Jun 24 Javascript
js监听鼠标点击和键盘点击事件并自动跳转页面
Sep 24 Javascript
jQuery中实现prop()函数控制多选框(全选,反选)
Aug 19 Javascript
js实现日历的简单算法
Jan 24 Javascript
AngularJS实现注册表单验证功能
Oct 16 Javascript
redux-saga 初识和使用
Mar 10 Javascript
JavaScript事件发布/订阅模式原理与用法分析
Aug 21 Javascript
微信小程序实现下拉菜单切换效果
Mar 30 Javascript
如何测量vue应用运行时的性能
Jun 21 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处理json时中文问题的解决方法
2011/04/12 PHP
php获取网页请求状态程序示例
2014/06/17 PHP
深入理解Yii2.0乐观锁与悲观锁的原理与使用
2017/07/26 PHP
PHP基于imagick扩展实现合成图片的两种方法【附imagick扩展下载】
2017/11/14 PHP
jQuery EasyUI API 中文文档 - Parser 解析器
2011/09/29 Javascript
window.onload和$(function(){})的区别介绍
2013/10/30 Javascript
转换字符串为json对象的方法详解
2013/11/29 Javascript
用Jquery实现滚动新闻
2014/02/12 Javascript
基于js里调用函数时,函数名带括号和不带括号的区别
2016/07/28 Javascript
Angular.JS去掉访问路径URL中的#号详解
2017/03/30 Javascript
JavaScript实现二维坐标点排序效果
2017/07/18 Javascript
vue 运用mock数据的示例代码
2017/11/07 Javascript
jQuery zTree 异步加载添加子节点重复问题
2017/11/29 jQuery
Vue-Access-Control 前端用户权限控制解决方案
2017/12/01 Javascript
jquery如何实现点击空白处隐藏元素
2017/12/05 jQuery
如何使用puppet替换文件中的string
2018/12/06 Javascript
vue拖拽组件 vuedraggable API options实现盒子之间相互拖拽排序
2019/07/08 Javascript
js中Function引用类型常见有用的方法和属性详解
2019/12/11 Javascript
微信小程序中data-key属性之数据传输(经验总结)
2020/08/22 Javascript
vue监听浏览器原生返回按钮,进行路由转跳操作
2020/09/09 Javascript
vue iview 隐藏Table组件里的某一列操作
2020/11/13 Javascript
JavaScript代码实现微博批量取消关注功能
2021/02/05 Javascript
[01:02:53]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第二局
2016/03/06 DOTA
[01:07:17]EG vs Optic Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
[02:58]魔廷新尊——痛苦女王至宝语音台词节选
2020/06/14 DOTA
python编写朴素贝叶斯用于文本分类
2017/12/21 Python
Python查找最长不包含重复字符的子字符串算法示例
2019/02/13 Python
python redis 批量设置过期key过程解析
2019/11/26 Python
Django-imagekit的使用详解
2020/07/06 Python
Nike爱尔兰官方网站:Nike.com (IE)
2018/03/12 全球购物
Theflamel意大利:女士奢华服装、鞋子和配件
2020/01/11 全球购物
《黄河颂》教学反思
2014/02/07 职场文书
农村优秀教师事迹材料
2014/08/27 职场文书
带香烟到学校抽的检讨书
2014/09/25 职场文书
股权转让协议范本
2014/12/07 职场文书
MySQL导致索引失效的几种情况
2022/06/25 MySQL