关于IE下AJAX的问题

前端之家收集整理的这篇文章主要介绍了关于IE下AJAX的问题前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

今天JS练手的时候,想封装一个发送AJAX请求的对象,当然,是想要兼容全浏览器的。代码如下:

  1. var Ajax = {
  2. xhr: null,callback: null,XMLHttp: function() {
  3. var xmlhttp;
  4. //标准浏览器
  5. if(window.XMLHttpRequest) {
  6. try {
  7. xmlhttp = new XMLHttpRequest();
  8. }
  9. catch(e) {
  10. alert('Unknown Ajax Error');
  11. //console.log('Unknown Ajax Error');
  12. }
  13. }
  14. //IE浏览器
  15. else {
  16. if(window.ActiveXObject) {
  17. try {
  18. xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
  19. }
  20. catch(e) {
  21. try {
  22. xmlhttp = new ActiveXObject('MSXML2.XMLHTTP');
  23. }
  24. catch(e) {
  25. alert('Unknown Ajax Error');
  26. //console.log('Unknown Ajax Error');
  27. }
  28. }
  29. }
  30. }
  31. return xmlhttp;
  32. },connect: function(paramsObj) {
  33. var PO = paramsObj;
  34. //判断传参合法性
  35. if(!(PO instanceof Object)) {
  36. alert('Ajax params illegal');
  37. //console.log('Ajax params illegal');
  38. return false;
  39. }
  40. else if(!(PO.url&&PO.method&&PO.callback)) {
  41. return false;
  42. }
  43. //初始化内部参数
  44. this.xhr = this.XMLHttp();
  45. this.callback = PO.callback;
  46. //遍历params对象并生成url参数
  47. var requestParams = '';
  48. if(PO.params) {
  49. for(key in Po.params) {
  50. requestParams += '&' + key + '=' + params[key];
  51. }
  52. requestParams = requestParams.substr(1);
  53. }
  54. //发起Ajax请求
  55. try {
  56. var xhr = this.xhr;
  57. xhr.onreadystatechange = this.response;
  58. //POST请求处理
  59. if(PO.method.toLowerCase()=='post') {
  60. xhr.open('POST',PO.url,true);
  61. xhr.send(requestParams);
  62. }
  63. //GET请求处理
  64. else if(PO.method.toLowerCase()=='get') {
  65. xhr.open('GET',PO.url+'?'+requestParams,true);
  66. xhr.send(null);
  67. }
  68. }
  69. catch(e) {
  70. this.callback(null,-1);
  71. }
  72. },response: function() {
  73. // 此段代码在全浏览器下测试通过
  74. // if(Ajax.xhr.readyState==4) {
  75. // if(Ajax.xhr.status=='200') {
  76. // Ajax.callback(Ajax.xhr.responseText);
  77. // }
  78. // else {
  79. // Ajax.callback(null,Ajax.xhr.status);
  80. // }
  81. // }
  82. //
  83. // 下面的代码在IE下失效(无报错,请求有相应,却没有返回结果),其它浏览器无此问题
  84. if(this.readyState==4) {
  85. if(this.status=='200') {
  86. Ajax.callback(this.responseText);
  87. }
  88. else {
  89. Ajax.callback(null,this.status);
  90. }
  91. }
  92. }
  93. };
  94.  
  95. //Ajax实例
  96. Ajax.connect({
  97. url: 'test.html',method: 'GET',callback: function(data,err) {
  98. if(data!=null) {
  99. alert(data);
  100. // console.log(data);
  101. }
  102. else {
  103. alert(err);
  104. // console.log(err);
  105. }
  106. }
  107. });

问题描述: 大家看一下我代码中有一块注释掉的代码,那块代码是在全浏览器下测试通过的。而没有注释掉的代码是有问题的代码,具体表现:

在Chrome,Firefox,Opera,Safari下测试通过,在IE6、7(IE8+没有测试)下的表现是:没有报错,也没有返回结果。

对比上下两块代码的不同,我想有两个可能,一个是this指向的问题,一个是IE下onreadystatechange函数执行的上下文环境有区别于其它浏览器。但是现在又无法确定问题,IE6、7下的JS调试又挺困难的(试了firebug-lite,但是没有想象中的好用,而且这个Ajax对象在firebug-lite下调用却成功了,有点糊涂)

解决过程:

其实测试方法很简单。主要是头脑一发热没想到,吃了个饭回来就恍然大悟。

其实JS在处理this指向不明的问题的时候,可以尝试使用this instanceof Object这类判断去了解它指向的是一个什么类型的变量。而对于判断是否为全局调用,则可以使用this===window。在这里我用的就是这个方法

代码出现问题的那一块,我们可以试着插入一段:

  1. alert(this instanceof Object);

结果发现,在IE6下,返回为false!一目了然!在IE下才可能出现如此诡异的返回值!证明什么?也就是说函数的执行上下文并非是对象!如此一来,在IE下就只能想到window对象了,要知道IE向来都是奇葩。你们标准浏览器说window对象是对象,我就偏不认。你还在怀疑我的看法?那何不试试?

  1. (this===window 结果是true!怎么样?没话说了吧?所以这样,问题就明朗了:

  2. IE下,AJAX请求得到响应后,回调函数onreadystatechange是在全局环境下被调用的。而在标准浏览器下,其执行上下文是XMLHttpRequest对象。故造成了我这次的“事故”。

猜你在找的Ajax相关文章