Jquery在IE7下无法使用 $.ajax解决方法(转)

本文介绍了解决在Internet Explorer 7中使用jQuery进行AJAX请求时遇到的问题。通过对jQuery源码的修改,实现了IE6、IE7及IE8等不同版本浏览器的兼容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在做系统测试的时候,原本用Jquery写了一个动态加载的树形菜单,发现在IE7下无法加载数据,(采用的是jquery1.3.2版本的$.ajax方法),上网查询到原来是IE7的执行ajax是用XMLHTTPRequest来声明的,经过对比果然如此;后采用以下的方法随即解决了问题。
通过查看源码发现
复制代码 代码如下:
// Create the request object; Microsoft failed to properly
// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
// This function can be overriden by calling jQuery.ajaxSetup
xhr:function(){
return window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
},

以下是这个jquery的源码的版本声明
复制代码 代码如下:
/*
* jQuery JavaScript Library v1.3.2
* http://jquery.com/
*
* Copyright (c) 2009 John Resig
* Dual licensed under the MIT and GPL licenses.
* http://docs.jquery.com/License
*
* Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
* Revision: 6246
*/

通过一个html打印“window.ActiveXObject ”的结果可以知道IE6、IE7和IE8都是返回的true,
测试的html源码为(同一个目录下有一个名为index.jsp页面,内容无所谓。)
复制代码 代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="javascript/jquery.js"></script>
<script type="text/javascript">
$(function (){
$.ajax({
http://www.cnblogs.com/mrhgw/admin/%22index.jsp",
success:function(){alert("success")},
error:function(){alert("error")}
});
//$("div").append("<font color='red'>window.ActiveXObject:</font>");
//$("div").append((window.ActiveXObject?"true":"false"));
//alert(typeof(new XMLHttpRequest()));
//alert(typeof(new ActiveXObject("Msxml2.XMLHTTP.4.0")));
//alert(typeof(new ActiveXObject("Msxml2.XMLHTTP")));
//alert(typeof(new ActiveXObject("Microsoft.XMLHTTP")));
});
</script>
</head>
<body>
<div></div>
</body>
</html>

情况一:
不修改源码,则IE6中可以弹出“success”的提示,而IE7却没有任何提示,连错误提示都没有。
情况二:
将源码中的
window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
修改为
window.ActiveXObject ? new XMLHttpRequest() : new XMLHttpRequest();
则IE7中是弹出“success”的提示,而IE6却提示js错误,详情大概为”XMLHttpRequest对象未定义“
两种情况下FireFox都可以正常提示“success”,版本是FireFox3.5.3,其他浏览器不知道。
由此可见IE7中需要使用new XMLHttpRequest()初始化ajax对象,IE6则使用new ActiveXObject("Microsoft.XMLHTTP")
但是jQuery源码中却没有对IE7的初始化方法进行兼容,而官网上的兼容说明是IE6+。
难道是我理解错误,还是其他的什么?希望大家给点意见,jQuery很好用,但是我不能要求客户必须用IE6,而放弃IE7啊!
最后多一句:
prototype最新版1.6.1也是同样的问题IE7下的Ajax.Request是没有作用的,需要将源码的1130行左右的
复制代码 代码如下:
var Ajax = {
getTransport: function() {
return Try.these(
function() {return new XMLHttpRequest()},
function() {return new ActiveXObject('Msxml2.XMLHTTP')},
//function() {return new ActiveXObject('Msxml2.XMLHTTP.4.0')},
function() {return new ActiveXObject('Microsoft.XMLHTTP')}
) || false;
},

进行修改,注释的那个部分是需要添加的修改。
这样才可以在IE7下使用这个ajax请求方法。
可是大家粗略的看一下,这里面的ajax初始化是先使用new XMLHttpRequest()创建,那就是说,
如果我不修改的话IE7应该也是可以的。
注:最后这个多一句的IE7兼容办法是在网络上搜索到的
以上就是我今天研究的结果,弄的我很糊涂,到底这个IE6、IE7和IE8全面兼容的jQuery的到底怎么实现(不能影响FireFox等等哦)
如果结论是:
由此可见IE7中需要使用new XMLHttpRequest()初始化ajax对象,IE6则使用new ActiveXObject("Microsoft.XMLHTTP")
那么prototype中的又怎么解释?
我已经糊涂了,希望大家指点一二!
刚才又搜索了一下关于XMLHttpRequest的创建方法,最后将源码修改为


return window.XMLHttpRequest? new XMLHttpRequest() : window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
则IE6\7\8和FF都可以运行了。
总算是解决了。

本文来自: 脚本之家(http://www.jb51.net/) 详细出处参考:http://www.jb51.net/article/20862.htm

<think>我们正在讨论使用HTML和jQuery通过`$.ajax`接收服务器发送事件(SSE)的实现方法。但需要注意的是,标准的SSE(Server-SentEvents)通常使用`EventSource`API实现,而不是通过`$.ajax`。因为`$.ajax`是基于XHR的,而XHR并不适合处理服务器推送的长连接。然而,如果由于某些原因(比如浏览器兼容性)必须使用`$.ajax`来模拟长轮询(longpolling)或者类似SSE的效果,我们可以尝试一种长轮询的方式,但这并不是真正的SSE。但是,根据引用[3]中提到,如果需要从服务器端推送数据给浏览器,可以使用WebSocket或服务器推送事件(SSE)。SSE有专门的`EventSource`接口,而`$.ajax`并不是为这种持续连接设计的。然而,如果用户坚持要用`$.ajax`来接收类似SSE的流,我们可以尝试使用长轮询(longpolling)技术。长轮询是客户端发送一个请求到服务器,服务器保持连接打开直到有新数据可发送,然后客户端收到响应后再立即发起新的请求。下面我将提供两种方案:1.使用标准的SSE(推荐)-使用`EventSource`2.使用jQuery的`$.ajax`模拟长轮询(类似SSE的效果)###方案1:使用标准SSE(推荐)SSE规范允许服务器向客户端推送事件。客户端使用`EventSource`对象接收事件。####客户端代码(HTML/JavaScript):```html<!DOCTYPEhtml><html><head><title>SSEExample</title></head><body><divid="sse-data"></div><script>//创建EventSource对象,连接到服务器端点consteventSource=newEventSource('sse-server.php');//监听消息事件eventSource.addEventListener('message',function(event){constdata=JSON.parse(event.data);//假设服务器发送的是JSON字符串document.getElementById('sse-data').innerHTML+=data.message+'<br>';});//监听错误事件eventSource.addEventListener('error',function(event){console.error('SSEerror:',event);//可以考虑重新连接});</script></body></html>```####服务器端示例(PHP):```php<?phpheader('Content-Type:text/event-stream');header('Cache-Control:no-cache');header('Connection:keep-alive');//设置服务器推送事件while(true){//获取需要推送的数据(这里用模拟数据)$data=['message'=>'Servertime:'.date('H:i:s')];//发送数据echo"data:".json_encode($data)."\n\n";ob_flush();flush();//等待一段时间再推送sleep(1);}```####注意事项:-服务器响应头必须包含`Content-Type:text/event-stream`。-事件流格式:每个事件由一行或多行文本组成,以两个换行符`\n\n`结束。每行格式可以是:-`data:{message}`-数据行-`event:{eventName}`-自定义事件名(默认为message事件)-`id:{id}`-事件ID-客户端通过`EventSource`对象监听事件。默认有`open`,`message`,`error`事件,也可以自定义事件。###方案2:使用jQuery的`$.ajax`模拟长轮询(非SSE,但能达到类似效果)如果我们不能使用`EventSource`(比如在旧版IE浏览器中),我们可以使用长轮询技术,即每次请求服务器,服务器在有数据时返回,然后客户端立即再次发起请求。####客户端代码(使用jQuery):```html<!DOCTYPEhtml><html><head><title>LongPollingExample</title><scriptsrc="https://code.jquery.com/jquery-3.6.0.min.js"></script></head><body><divid="longpoll-data"></div><script>functionlongPolling(){$.ajax({url:'longpoll-server.php',method:'GET',dataType:'json',success:function(data){//处理接收到的数据$('#longpoll-data').append(data.message+'<br>');//立即再次发起请求longPolling();},error:function(xhr,status,error){console.error('Longpollingerror:',error);//错误后延迟一段时间再重试setTimeout(longPolling,2000);}});}//开始长轮询$(document).ready(function(){longPolling();});</script></body></html>```####服务器端(PHP):```php<?phpheader('Content-Type:application/json');header('Cache-Control:no-cache');//模拟等待新数据(实际中可能是等待数据库更新、消息队列等)$hasNewData=false;$startTime=time();//设置最长等待时间(秒),避免连接占用太久$maxWait=30;while(!$hasNewData){//检查是否有新数据(这里模拟每5秒产生一次新数据)if(time()-$startTime>=5){$hasNewData=true;$data=['message'=>'Updateat'.date('H:i:s')];}else{//短暂睡眠以减少CPU占用usleep(500000);//0.5秒}//如果超过最大等待时间,则返回空数据或超时信息if(time()-$startTime>=$maxWait){$data=['message'=>'Timeout'];$hasNewData=true;}}echojson_encode($data);```####注意事项:-长轮询会持续占用一个HTTP连接,服务器需要支持高并发长连接。-每次收到响应后立即发起下一次请求,这样可能会有频繁的请求。但相比短轮询(定时请求),长轮询在数据实时性上更好,且减少了无效请求。-服务器端需要控制超时,避免长时间占用连接而没有数据返回。-错误处理:当请求失败时(如网络问题),应延迟一段时间再重试,避免频繁重试加重服务器负担。###总结-如果浏览器支持(大部分现代浏览器都支持),**强烈建议使用SSE(方案1)**,因为它是为服务器推送事件设计的,实现更简单,效率更高。-如果必须兼容旧版浏览器(如IE),可以考虑使用长轮询(方案2)或者使用polyfill(如`EventSource`的polyfill,但注意IE完全不支持SSE,polyfill也是用长轮询模拟的)。-另外,引用[3]中提到,如果需要从服务器端推送数据,SSE规范简单,实现容易。所以,在条件允许的情况下,优先使用SSE。###相关问题1.服务器发送事件(SSE)与WebSocket有什么区别?2.如何确保SSE连接在断开后能够自动重连?3.在服务器端实现SSE时,如何处理多个客户端连接?4.长轮询和短轮询各有什么优缺点?5.使用SSE时,如何实现身份验证?</think>### 使用jQuery$.ajax实现服务器发送事件(SSE) 虽然标准的SSE实现使用`EventSource` API,但通过jQuery的`$.ajax`结合长轮询技术也可以模拟SSE效果。以下是具体实现方法和注意事项: #### 实现方案 ```html <!DOCTYPE html> <html> <head> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> </head> <body> <div id="sse-data"></div> <script> let lastEventId = 0; // 跟踪最后接收的事件ID function connectSSE() { $.ajax({ url: 'sse-server.php', method: 'GET', data: { lastEventId: lastEventId }, // 发送最后接收的事件ID dataType: 'text', timeout: 0, // 禁用超时 success: function(data) { // 处理事件数据 const events = data.split('\n\n'); events.forEach(event => { if(event.includes('data:')) { const message = event.match(/data: (.+)/)[1]; $('#sse-data').append(`<p>${message}</p>`); lastEventId++; // 更新最后接收的事件ID } }); // 立即重新连接 connectSSE(); }, error: function(xhr) { console.error('SSE连接错误:', xhr.statusText); // 2秒后重连 setTimeout(connectSSE, 2000); } }); } $(document).ready(connectSSE); </script> </body> </html> ``` #### 服务器端示例(PHP) ```php <?php // sse-server.php header('Content-Type: text/event-stream'); header('Cache-Control: no-cache'); header('Connection: keep-alive'); $lastId = $_GET['lastEventId'] ?? 0; while (true) { // 检查新数据(实际应用中查询数据库或消息队列) if ($lastId < getLatestEventId()) { $data = [ 'id' => $lastId + 1, 'message' => '事件数据 @ ' . date('Y-m-d H:i:s') ]; // 发送SSE格式数据 echo "id: {$data['id']}\n"; echo "data: " . json_encode($data) . "\n\n"; ob_flush(); flush(); $lastId = $data['id']; } sleep(1); // 降低CPU占用 } function getLatestEventId() { // 模拟获取最新事件ID return rand(1, 100); } ``` ### 关键注意事项 1. **连接管理** - 必须禁用超时:`timeout: 0` - 每次请求结束立即发起新请求(长轮询) - 错误处理中必须包含重连机制 - 需要跟踪`lastEventId`实现断点续传[^1] 2. **服务器端要求** - 响应头必须包含: ```http Content-Type: text/event-stream Cache-Control: no-cache Connection: keep-alive ``` - 数据格式必须遵守SSE规范: ``` id: [事件ID]\n data: [JSON数据]\n\n ``` - 使用`ob_flush()`和`flush()`确保即时输出 3. **性能优化** - 避免频繁请求:服务器应在有数据时返回,无数据时等待(如示例中的`sleep(1)`) - 使用事件ID防止数据丢失 - 限制单次返回事件数量(防止响应过大) 4. **浏览器兼容性** - 此方案兼容不支持`EventSource`的浏览器(如IE11) - 现代浏览器建议优先使用原生`EventSource` API[^3] 5. **安全考虑** - 在HTTPS环境下使用 - 验证`Origin`头防止CSRF攻击 - 对敏感数据实施身份验证 ### 替代方案建议 对于现代浏览器项目,建议直接使用标准SSE API: ```javascript const source = new EventSource('/sse-endpoint'); source.onmessage = (event) => { console.log(JSON.parse(event.data)); }; ``` 这种方式更高效且符合HTML5标准[^3]。 ### 相关问题 1. 如何确保SSE连接在弱网环境下的稳定性? 2. 服务器发送事件(SSE)与WebSocket的主要区别是什么? 3. 如何实现SSE连接的认证和授权机制? 4. 在SSE通信中如何处理二进制数据? 5. 如何监控和调试SSE连接的性能问题?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值