一份老外写的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 new一个对象的实质
Jan 07 Javascript
javascript中运用闭包和自执行函数解决大量的全局变量问题
Dec 30 Javascript
关于动态执行代码(js的Eval)实例详解
Aug 15 Javascript
jQuery实现的瀑布流加载效果示例
Sep 13 Javascript
不使用script导入js文件的几种方法
Oct 27 Javascript
BootStrap实现响应式布局导航栏折叠隐藏效果(在小屏幕、手机屏幕浏览时自动折叠隐藏)
Nov 30 Javascript
tab栏切换原理
Mar 22 Javascript
vue语法之拼接字符串的示例代码
Oct 25 Javascript
React中使用async validator进行表单验证的实例代码
Aug 17 Javascript
layui 动态设置checbox 选中状态的例子
Sep 02 Javascript
在vue中使用Echarts画曲线图的示例
Oct 03 Javascript
react+antd 递归实现树状目录操作
Nov 02 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
javascript qq右下角滑出窗口 sheyMsg
2010/03/21 Javascript
设置checkbox为只读(readOnly)的两种方式
2013/10/11 Javascript
js创建对象的区别示例介绍
2014/07/24 Javascript
JQuery $.each遍历JavaScript数组对象实例
2014/09/01 Javascript
JavaScript拆分字符串时产生空字符的解决方案
2014/09/26 Javascript
node.js中的fs.readFile方法使用说明
2014/12/15 Javascript
JS判断键盘是否按的回车键并触发指定按钮点击操作的方法
2017/02/13 Javascript
jQuery表单设置值的方法
2017/06/30 jQuery
Vue + better-scroll 实现移动端字母索引导航功能
2018/05/07 Javascript
JavaScript中构造函数与原型链之间的关系详解
2019/02/25 Javascript
VueJS 取得 URL 参数值的方法
2019/07/19 Javascript
node.js实现带进度条的多文件上传
2020/03/27 Javascript
微信小程序绘制半圆(弧形)进度条
2020/11/18 Javascript
python修改注册表终止360进程实例
2014/10/13 Python
Python爬取Coursera课程资源的详细过程
2014/11/04 Python
Python MySQLdb模块连接操作mysql数据库实例
2015/04/08 Python
在Python中操作时间之tzset()方法的使用教程
2015/05/22 Python
Python中的urllib模块使用详解
2015/07/07 Python
python制作websocket服务器实例分享
2016/11/20 Python
Django基于ORM操作数据库的方法详解
2018/03/27 Python
numpy的文件存储.npy .npz 文件详解
2018/07/09 Python
Tensorflow使用支持向量机拟合线性回归
2018/09/07 Python
python__name__原理及用法详解
2019/11/02 Python
numpy.linalg.eig() 计算矩阵特征向量方式
2019/11/29 Python
Python流程控制语句的深入讲解
2020/06/15 Python
20行Python代码实现一款永久免费PDF编辑工具的实现
2020/08/27 Python
美国环保妈妈、儿童和婴儿用品购物网站:The Tot
2019/11/24 全球购物
英语师范专业毕业生自荐信
2013/09/21 职场文书
表彰先进集体通报
2014/01/12 职场文书
鲜果饮品店创业计划书
2014/01/21 职场文书
社区健康教育实施方案
2014/03/18 职场文书
幼儿园标语大全
2014/06/19 职场文书
教师反腐倡廉演讲稿
2014/09/03 职场文书
2016入党积极分子党校培训心得体会
2016/01/06 职场文书
PyTorch dropout设置训练和测试模式的实现
2021/05/27 Python
排查并解决MySQL生产库内存使用率高的报警
2022/04/11 MySQL