一份老外写的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 相关文章推荐
jquery 插件之仿“卓越亚马逊”首页弹出菜单效果
Dec 25 Javascript
A标签中通过href和onclick传递的this对象实现思路
Apr 19 Javascript
JS 获取select(多选下拉)中所选值的示例代码
Aug 02 Javascript
js实现按钮控制图片360度翻转特效的方法
Feb 17 Javascript
jQuery判断浏览器并动态调整select宽度的方法
Mar 02 Javascript
快速解决Canvas.toDataURL 图片跨域的问题
May 10 Javascript
JavaScript纯色二维码变成彩色二维码
Jul 23 Javascript
Vue Cli与BootStrap结合实现表格分页功能
Aug 18 Javascript
vue-router路由与页面间导航实例解析
Nov 07 Javascript
vue filter 完美时间日期格式的代码
Aug 14 Javascript
Vue父子传递实例讲解
Feb 14 Javascript
Vue生命周期activated之返回上一页不重新请求数据操作
Jul 26 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
学习discuz php 引入文件的方法DISCUZ_ROOT
2009/06/21 PHP
基于initPHP的框架介绍
2013/04/18 PHP
php实现TCP端口检测的方法
2015/04/01 PHP
Symfony2创建页面实例详解
2016/03/18 PHP
Yii核心验证器api详解
2016/11/23 PHP
PHP查询分页的实现代码
2017/06/09 PHP
阿里云的WindowsServer2016上部署php+apache
2018/07/17 PHP
可以把编码转换成 gb2312编码lib.UTF8toGB2312.js
2007/08/21 Javascript
JavaScript 版本自动生成文章摘要
2008/07/23 Javascript
解决jquery的datepicker的本地化以及Today问题
2012/05/23 Javascript
Javascript页面添加到收藏夹的简单方法
2013/08/07 Javascript
Jquery通过Ajax方式来提交Form表单的具体实现
2013/11/07 Javascript
js获取时间并实现字符串和时间戳之间的转换
2015/01/05 Javascript
jQuery插件Skippr实现焦点图幻灯片特效
2015/04/12 Javascript
JS实现获取键盘按下的按键并显示在页面上的方法
2015/11/04 Javascript
Vue.js每天必学之过滤器与自定义过滤器
2016/09/07 Javascript
javascript实现秒表计时器的制作方法
2017/02/16 Javascript
layui use 定义js外部引用函数的方法
2019/09/26 Javascript
jquery实现垂直手风琴导航栏
2020/02/18 jQuery
详细分析vue响应式原理
2020/06/22 Javascript
使用Python实现简单的服务器功能
2017/08/25 Python
Python实现中一次读取多个值的方法
2018/04/22 Python
Python实现多进程的四种方式
2019/02/22 Python
详解Python3 中的字符串格式化语法
2020/01/15 Python
python用什么编辑器进行项目开发
2020/06/17 Python
Myprotein亚太地区:欧洲第一在线运动营养品牌
2020/12/20 全球购物
业务经理岗位职责
2013/11/11 职场文书
医大实习自我鉴定
2013/12/07 职场文书
管理心得体会
2013/12/28 职场文书
报社实习生自荐信
2014/01/24 职场文书
出生证明公证书
2014/04/09 职场文书
2015年党员承诺书
2015/01/21 职场文书
教师个人总结范文
2015/02/11 职场文书
导游词幽默开场白
2019/06/26 职场文书
golang 实用库gotable的具体使用
2021/07/01 Golang
python如何查找列表中元素的位置
2022/05/30 Python