今天JS练手的时候,想封装一个发送AJAX请求的对象,当然,是想要兼容全浏览器的。代码如下:
var Ajax = {
xhr: null,
callback: null,
XMLHttp: function() {
var xmlhttp;
//标准浏览器
if(window.XMLHttpRequest) {
try {
xmlhttp = new XMLHttpRequest();
}
catch(e) {
alert('Unknown Ajax Error');
//console.log('Unknown Ajax Error');
}
}
//IE浏览器
else {
if(window.ActiveXObject) {
try {
xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
}
catch(e) {
try {
xmlhttp = new ActiveXObject('MSXML2.XMLHTTP');
}
catch(e) {
alert('Unknown Ajax Error');
//console.log('Unknown Ajax Error');
}
}
}
}
return xmlhttp;
},
connect: function(paramsObj) {
var PO = paramsObj;
//判断传参合法性
if(!(PO instanceof Object)) {
alert('Ajax params illegal');
//console.log('Ajax params illegal');
return false;
}
else if(!(PO.url&&PO.method&&PO.callback)) {
return false;
}
//初始化内部参数
this.xhr = this.XMLHttp();
this.callback = PO.callback;
//遍历params对象并生成url参数
var requestParams = '';
if(PO.params) {
for(key in Po.params) {
requestParams += '&' + key + '=' + params[key];
}
requestParams = requestParams.substr(1);
}
//发起Ajax请求
try {
var xhr = this.xhr;
xhr.onreadystatechange = this.response;
//POST请求处理
if(PO.method.toLowerCase()=='post') {
xhr.open('POST',PO.url,true);
xhr.send(requestParams);
}
//GET请求处理
else if(PO.method.toLowerCase()=='get') {
xhr.open('GET',PO.url+'?'+requestParams,true);
xhr.send(null);
}
}
catch(e) {
this.callback(null,-1);
}
},
response: function() {
// 此段代码在全浏览器下测试通过
// if(Ajax.xhr.readyState==4) {
// if(Ajax.xhr.status=='200') {
// Ajax.callback(Ajax.xhr.responseText);
// }
// else {
// Ajax.callback(null,Ajax.xhr.status);
// }
// }
//
// 下面的代码在IE下失效(无报错,请求有相应,却没有返回结果),其它浏览器无此问题
if(this.readyState==4) {
if(this.status=='200') {
Ajax.callback(this.responseText);
}
else {
Ajax.callback(null,this.status);
}
}
}
}; //Ajax实例
Ajax.connect({
url: 'test.html',
method: 'GET',
callback: function(data,err) {
if(data!=null) {
alert(data);
// console.log(data);
}
else {
alert(err);
// console.log(err);
}
}
});
问题描述: 大家看一下我代码中有一块注释掉的代码,那块代码是在全浏览器下测试通过的。而没有注释掉的代码是有问题的代码,具体表现:
在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。在这里我用的就是这个方法。
在代码出现问题的那一块,我们可以试着插入一段:
alert(this instanceof Object);
结果发现,在IE6下,返回为false!一目了然!在IE下才可能出现如此诡异的返回值!证明什么?也就是说函数的执行上下文并非是对象!如此一来,在IE下就只能想到window对象了,要知道IE向来都是奇葩。你们标准浏览器说window对象是对象,我就偏不认。你还在怀疑我的看法?那何不试试?
alert(this===window);
结果是true!怎么样?没话说了吧?所以这样,问题就明朗了:
在IE下,AJAX请求得到响应后,回调函数onreadystatechange是在全局环境下被调用的。而在标准浏览器下,其执行上下文是XMLHttpRequest对象。故造成了我这次的“事故”。
关于IE下AJAX的问题探讨的更多相关文章
-
MVC 下 ajax调用 日期差值计算
背景: 服务项目已有服务期起止时间From-To 现在要根据用户输入的新的起始时间, 和该服务期的原有区间值, 计算出新的服务期截止时间 即 NewServiceToDateTime = NewSer ...
-
ie8或9下ajax跨域问题
ie8或9下ajax跨域支持,添加如下代码 <!--[if (IE 8)|(IE 9)]><script src="https://cdn.bootcss.com/jque ...
-
SpringMVC下Ajax请求的方法,@Responsebody如果返回的是布尔值,ajax不会接到任何回传数据
SpringMVC框架下,如果用ajax向后台请求得方法如果使用@Responsebody返回布尔值的话,ajax得不到任何的回传数据. 但是如果返回String类型,就是正常的. 测试了下代码写得没 ...
-
IE浏览器下ajax缓存导致数据不更新的解决方法
摘自:http://www.iefans.net/ie-ajax-json-shuju-huancun/ 最近做设计的时候遇到一个小问题,当你用jquery的getjson函数从后台获取数据的时候,I ...
-
七牛---以一个七牛上传的实例小结下AJAX跨域【转】
http://blog.csdn.net/netdxy/article/details/50699842 使用七牛过程中,很多用户或多或少遇到跨域的问题,这篇文章主要介绍下跨域的概念来看什么情况下会出 ...
-
***Jquery下Ajax与PHP数据交换
一.前台传递字符串变量,后台返回字符串变量(非json格式) Javascript代码: 这里,为了解决Ajax数据传递出现的汉字乱码,在字符串传递之前,使用javascript函数escape()对 ...
-
IE9下Ajax缓存问题
使用jQuery的getJSON从后台定时获取数据并刷新界面,使用以下方法时,在Chrome,Firefox下没问题,但在IE9下却无法刷新数据 $.getJSON(webApp + "/G ...
-
解决IE下Ajax请求无效
在做web开发是,大多时候都会使用FireFox作为调试的浏览器.上面携带的FireBug用来调试JavaScript实在是太方便了,绝大多数的问题都能够通过它跟踪调试出来.但是,当项目发布时,不能仅 ...
-
springmvc框架下ajax请求传参数中文乱码解决
springmvc框架下jsp界面通过ajax请求后台数据,传递中文参数到后台显示乱码 解决方法:js代码 运用encodeURI处理两次 /* *掩码处理 */ function maskWord( ...
随机推荐
-
python 函数的调用 和执行 小知识
1.符号表 执行一个函数会引入一个用于函数的局部变量的新符号表. 更确切地说, 函数中的所有的赋值都是将值存储在局部符号表: 而变量引用首先查找局部符号表, 然后是上层函数的局部符号表, 然后是全局符 ...
-
SRM 594 DIV1 250
可能开始宿舍比较乱,思绪静不下来...想了大半个小时,终于确定了应该暴力+DP,然后写了枚举除数,和被除的版本..这样,还敲错了个字母,第一次提交还100多,修改提交还有75.多,最后想到,貌似不打对 ...
-
【转】Android自定义View的实现方法,带你一步步深入了解View(四)
原文网址: 转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17357967 不知不觉中,带你一步步深入了解View系列的文章已经写到 ...
-
Rational Rose与UML教程
在学UML的过程中,Rational Rose的角色无比重要.现在能找到的大多数是2003的,但下面连接是2007. http://blog.csdn.net/skl_TZ/article/detai ...
-
手机下的ev.pageX无效
把 ev.pageX 换成 e.originalEvent.targetTouches[0].pageX; 例子: var start_x, start_y, end_x, end_y, ...
-
angular的小实例
主要是使用了angular的指令. 学习地址:http://www.runoob.com/angularjs/angularjs-tutorial.html 1. 效果: 输入数据剩余字数会相应减少, ...
-
Linux串口通信之termios结构体说明
termios结构体中,该结构体一般包括如下的成员:tcflag_t c_iflag; tcflag_t c_oflag; tcflag_t c_cflag; tcfla ...
-
LOJ #6374「SDWC2018 Day1」网格
模拟赛考过的题 当时太菜了现在也一样只拿到了$ 30$分 回来填个坑 LOJ #6374 题意 你要从$ (0,0)$走到$ (T_x,T_y)$,每次移动的坐标增量满足$ 0 \leq \Delta ...
-
天天向上的力量 III
描述 一年365天,以第1天的能力值为基数,记为1.0. 当好好学习时,能力值相比前一天提高N‰:当没有学习时,能力值相比前一天下降N‰. 每天努力或放任,一年下来的能力值相差多少呢?其中,N的取值范 ...
-
Effective C++学习笔记之#define
前言 条款02:尽量以const.enum.inline替换#define:尽可能用编译器代替不必要的预处理器. 内容 一.对于单纯常量 1.const 有两种特殊的const,常量指针和class专 ...