`

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

 
阅读更多

/* 

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; 
  }; 
}
分享到:
评论

相关推荐

    不同浏览器创建XMLHttpRequest,兼容各种浏览器(王兴魁老师视频笔记)

    总结起来,创建XMLHttpRequest对象并实现跨浏览器兼容性是一项关键任务,它涉及到对各种浏览器特性的理解和适配。通过学习王兴魁老师的课程,开发者可以深入掌握这一技术,并在实际项目中灵活运用,提升用户体验。在...

    javascript解决浏览器兼容性问题

    ### JavaScript 解决浏览器兼容性问题...然而,随着新型浏览器的不断涌现(例如Google Chrome),未来可能会出现更多的兼容性挑战。因此,持续关注浏览器特性的变化,并灵活调整代码以适应不同环境的需求是至关重要的。

    Ajax 创建XMLHttpRequest对象,兼容所有主流浏览器(IE5除外)

    经测试,用此方法创建XMLHttpRequest对象,在运用AJAX的时候,可以的兼容IE6,IE7,IE8,Opera,Safari,Google Chrome,fireFox。主流的应该就这些吧?theWorld,遨游等浏览器都是以IE为核心的,所以肯定也没问题。 另外...

    支持多种浏览器创建XMLHttpRequest对象代码

    ### 支持多种浏览器创建XMLHttpRequest对象代码 随着Web技术的发展与演进,跨浏览器兼容性一直是前端开发者面临的重要挑战之一。特别是在处理Ajax请求时,如何优雅地在不同浏览器(尤其是IE与其他现代浏览器)间...

    Ajax-hook:拦截由XMLHttpRequest发出的浏览器的AJAX请求-js源码

    在源网页加载之前,实现一个XMLHttpRequest的代理对象,然后覆盖全局的XMLHttpRequest,这样一但上层调用 new XMLHttpRequest这样的代码时,其实创建的是Ajax-hook的代理对象实例

    WEB浏览器兼容性开发宝典

    在Web开发领域,浏览器兼容性始终是一个不可忽视的重要问题。"WEB浏览器兼容性开发宝典"聚焦于解决IE(Internet Explorer)与Firefox浏览器之间存在的差异,帮助开发者在跨平台环境中创建一致的用户体验。这个资源包...

    HTML5+JQUERY文件上传,手机浏览器兼容性好(asp.net例子) 源码

    HTML5和jQuery是现代网页开发中的重要技术,它们在文件上传功能方面提供了强大的支持,尤其在考虑到手机浏览器的兼容性时。在这个asp.net示例中,我们探讨如何利用这两者来实现一个高效的文件上传功能。 首先,...

    拦截由XMLHttpRequest发出的浏览器http请求.zip

    上述代码中的`xhrInterceptor`函数创建了一个新的XMLHttpRequest实例,重写了`open`和`send`方法。这样,每次创建的新XHR实例都会执行我们定义的拦截逻辑。 此外,现代浏览器提供了更高级的API——Fetch API,它也...

    上传图片并且浏览--各种浏览器都兼容的代码

    为了实现这一功能,开发者需要考虑多种浏览器的兼容性问题,确保代码在不同的浏览器环境下都能正常工作。以下是一些关于如何实现这个功能的关键知识点: 1. **HTML表单**:首先,我们需要在HTML中创建一个文件上传...

    XMLHTTP多浏览器兼容性写法

    需要注意的是,在某些浏览器中,可能存在兼容性问题,例如,某些浏览器可能不支持XMLHttpRequest对象或ActiveXObject对象。在这种情况下,我们可以使用alert语句提示用户,并redirect到非Ajax页面中。 if(!xmlhttp)...

    兼容多个浏览器的单文件上传

    本项目"兼容多个浏览器的单文件上传"就是针对这个问题,提供了一种解决方案,确保在IE6、7、8这些低版本浏览器中也能实现类似现代浏览器的无刷新异步上传效果。 首先,我们来看文件上传的基本原理。在HTML中,`...

    解决异步验证 浏览器不兼容的问题

    这里提到的"dbank.js"可能是一个为解决浏览器兼容性问题而设计的JavaScript库。这个库可能包含了处理异步验证的函数和方法,能自动适配不同的浏览器环境,提供统一的API来发起异步请求和处理响应。使用这样的库可以...

    兼容浏览器的解析xml的js代码

    在JavaScript中,解析XML文档并使用XPath进行查询是一项常见的任务,尤其在开发跨浏览器的Web应用时,确保代码兼容性尤为重要。XPath是一种在XML文档中查找信息的语言,它允许我们根据节点的名称、属性、值或其他...

    弹出层兼容所有浏览器

    实现跨浏览器兼容性是一项挑战,因为不同的浏览器可能对CSS样式、JavaScript语法和API支持程度不同。以下是一些关键策略: 1. **CSS前缀**:不同浏览器对CSS3新特性的支持程度不同,例如动画、过渡和变形等。使用-...

    WEB浏览器支持库

    在Web开发领域,浏览器支持库是至关重要的,因为它们确保了不同浏览器之间的兼容性,使得网站和应用能在各种环境下正常运行。 描述 "WEB浏览器" 是对标题的补充,进一步明确了我们将关注的是Web浏览器的相关技术。...

    jQuery解决浏览器兼容性问题案例分析

    jQuery在处理浏览器兼容性问题上有多方面的策略。例如,它统一了CSS选择器的实现,使得开发者可以使用W3C标准的CSS选择器,而不必关心浏览器的实现差异。jQuery还提供了`.show()`, `.hide()`, `.fadeIn()`, `....

    Firefox浏览器兼容JS脚本供参考

    在开发Web应用时,浏览器兼容性是一个常见的挑战,特别是JavaScript脚本在不同的浏览器上可能会有不同的行为。本文将详细解析在Firefox浏览器中实现JS脚本兼容的一些关键点,以确保代码在Firefox和其他浏览器上的...

    自定义js库,解决浏览器不兼容问题

    在JavaScript的世界里,浏览器兼容性问题一直是一个棘手的话题。开发者常常需要面对不同浏览器对同一段JS代码解析和执行方式的差异,这给代码的编写和维护带来了挑战。为了解决这个问题,创建一个自定义的js库是一个...

Global site tag (gtag.js) - Google Analytics