一份老外写的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 相关文章推荐
一个可以兼容IE FF的加为首页与加入收藏实现代码
Nov 02 Javascript
js 利用className得到对象的实现代码
Nov 15 Javascript
用JQuery实现表格隔行变色和突出显示当前行的代码
Feb 10 Javascript
JQuery设置文本框和密码框得到焦点时的样式
Aug 30 Javascript
键盘KeyCode值列表汇总
Nov 26 Javascript
js使下拉列表框可编辑不止是选择
Dec 12 Javascript
浅析javascript中函数声明和函数表达式的区别
Feb 15 Javascript
纯javascript判断查询日期是否为有效日期
Aug 24 Javascript
JS实现拖拽的方法分析
Dec 20 Javascript
详解JavaScript添加给定的标签选项
Sep 17 Javascript
微信小程序实现单选选项卡切换效果
Jun 19 Javascript
JS桶排序的简单理解与实现方法示例
Nov 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作的文本留言本的例子(三)
2006/10/09 PHP
PHP与SQL注入攻击[一]
2007/04/17 PHP
php数组函数序列之array_intersect() 返回两个或多个数组的交集数组
2011/11/10 PHP
PHP解析目录路径的3个函数总结
2014/11/18 PHP
PHP使用strrev翻转中文乱码问题的解决方法
2017/01/13 PHP
thinkphp3.2框架中where条件查询用法总结
2019/08/13 PHP
js常见表单应用技巧
2008/01/09 Javascript
javascript 触发HTML元素绑定的函数
2010/09/11 Javascript
编写可维护面向对象的JavaScript代码[翻译]
2011/02/12 Javascript
jQuery EasyUI API 中文文档 - ValidateBox验证框
2011/10/06 Javascript
jQuery 选择表格(table)里的行和列及改变简单样式
2012/12/15 Javascript
js验证真实姓名与身份证号是否匹配
2015/10/13 Javascript
js绘制购物车抛物线动画
2020/11/18 Javascript
纯JS打造网页中checkbox和radio的美化效果
2016/10/13 Javascript
ES6中module模块化开发实例浅析
2017/04/06 Javascript
jQuery中.attr()和.data()的区别分析
2017/09/03 jQuery
vue动态路由配置及路由传参的方式
2018/05/23 Javascript
Vue+webpack+Element 兼容问题总结(小结)
2018/08/16 Javascript
Vuejs学习笔记之使用指令v-model完成表单的数据双向绑定
2019/04/29 Javascript
基于vue手写tree插件的那点事儿
2019/08/20 Javascript
jQuery 动态粒子效果示例代码
2020/07/07 jQuery
Python的ORM框架SQLObject入门实例
2014/04/28 Python
Python下载指定页面上图片的方法
2016/05/12 Python
Python 正则表达式的高级用法
2016/12/04 Python
Python实现投影法分割图像示例(一)
2020/01/17 Python
python实现从尾到头打印单链表操作示例
2020/02/22 Python
Python实现区域填充的示例代码
2021/02/03 Python
浏览器实现移动端高性能css3动画(开启gpu加速)
2013/12/23 HTML / CSS
纯CSS3发光分享按钮的实现教程
2014/09/06 HTML / CSS
英国电动工具购买网站:Anglia Tool Centre
2017/04/25 全球购物
《草虫的村落》教学反思
2014/02/16 职场文书
《秋游》教学反思
2014/04/24 职场文书
大学生就业协议书范本(适用于公司企业)
2014/10/07 职场文书
2016年全国爱牙日宣传活动总结
2016/04/05 职场文书
德生TECSUN S-2000使用手册文字版
2022/05/10 无线电
教你如何用cmd快速登录服务器
2022/06/10 Servers