IE9的F12工具,"网络"页签,点击"开始捕获"之后,请求显示的状态是"挂起"的分析和解决

      最近一个项目,客户端使用用jQuery编写ajax请求,服务端采用struts2框架。js发送请求和action处理请求过程中,遇到一个问题。刚开始觉得问题很诡异,仔细定位很久之后才发现问题,虽然问题解决了, 但更深层次的原因还不清楚,欢迎大牛们指导。

1.问题现象

  • 客户端问题
            通过IE9下的开发人员工具F12发现,浏览器的确是发送了post请求,但是该请求“结果”栏显示的是“已终止”,“发起程序”值 是“已挂起”。请求头、请求体、响应头、响应体都是空的。也就说浏览器发送了1个异常的请求。
  • 服务端问题
          Struts2的action能够接受到post的请求,但是获取不到请求参数的值。
 

2.相关JS代码

[javascript] view plain copy print?
  1. function sendMessage()     
  2. {    
  3.   $.post("indvAction!sendShortMsg.action", {    
  4.      "configType" : "1"    
  5.   });    
  6. }    
  7.      
  8. //弹出确认对话框    
  9. Nf.promptConfirm({    
  10.                   message :”operation success”,  
  11.                   width : 300,  
  12.                   height : 150,   
  13.                   handler : function(btn)  
  14.                             {  
  15.                                 if (btn == "ok")   
  16.                                 {    
  17.                                     //向服务器发送ajax请求    
  18.                                     sendMessage()  
  19.                                     //关闭当前页面    
  20.                                     NfLayout.closeTab();    
  21.                                 }    
  22.                               
  23.                             }  
  24.   
  25.                   });  
function sendMessage()   
{  
  $.post("indvAction!sendShortMsg.action", {  
     "configType" : "1"  
  });  
}  
   
//弹出确认对话框  
Nf.promptConfirm({  
                  message :”operation success”,
				  width : 300,
				  height : 150, 
				  handler : function(btn)
							{
								if (btn == "ok") 
								{  
									//向服务器发送ajax请求  
									sendMessage()
									//关闭当前页面  
									NfLayout.closeTab();  
								}  
							
							}

                  });

3.定位过程

    刚开始使用F12没有得到与定位问题有关的信息。后面使用httpWatch或burp suite进行http抓包,查看原始的http请求和响应报文。结果发现了问题。
 
1、浏览器发出的请求报文中,的确没有传递configType字段的值。请求报文如下:         
  1. POST /mobile/jsp/indvconfig/indvAction!sendShortMsg.action HTTP/1.1  
  2. x-requested-with: XMLHttpRequest  
  3. Accept-Language: zh-CN,en;q=0.5  
  4. Referer: https://*.*.*.*:17243/mobile/jsp/indvconfig/indv_config.jsp  
  5. Accept: */*  
  6. Content-Type: application/x-www-form-urlencoded  
  7. Accept-Encoding: gzip, deflate  
  8. User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)  
  9. Host: 11.12.213.87:17243  
  10. Content-Length: 0  
  11. Connection: Keep-Alive  
  12. Cache-Control: no-cache  
  13. Cookie: JSESSIONID=62C9FF9CBC97731B120ABAC297C4E4C5  
POST /mobile/jsp/indvconfig/indvAction!sendShortMsg.action HTTP/1.1
x-requested-with: XMLHttpRequest
Accept-Language: zh-CN,en;q=0.5
Referer: https://*.*.*.*:17243/mobile/jsp/indvconfig/indv_config.jsp
Accept: */*
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
Host: 11.12.213.87:17243
Content-Length: 0
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=62C9FF9CBC97731B120ABAC297C4E4C5
 2、浏览器的确收到了服务器的响应报文。
  1. HTTP/1.1 200 OK  
  2. Server: Apache-Coyote/1.1  
  3. Content-Type: text/plain;charset=UTF-8  
  4. Vary: Accept-Encoding  
  5. Date: Fri, 22 Nov 2013 01:34:31 GMT  
  6. Content-Length: 6  
  7.   
  8. this is my response!  
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/plain;charset=UTF-8
Vary: Accept-Encoding
Date: Fri, 22 Nov 2013 01:34:31 GMT
Content-Length: 6

this is my response!
其实一切都很正常了,浏览器确实发送了HTTP请求,只不过是没有携带请求参数值,只不过是被IE9的展示方式欺骗了,所以刚开始定位很久都没有头绪。现在产生了如下问题:为什么浏览器发送了ajax请求,但是没有携带请求参数?为什么IE9显示请求是“已挂起”、“已终止”
 

4.问题解决

    去掉NfLayout.closeTab();这行代码就可以解决问题了。这是因为jquery的POST请求是异步的,当post请求还没有准备好数据的时候,这个时候执行了NfLayout.closeTab();当前页面关闭,导致了浏览器终止了http请求。这样的话就,相当于是请求被异常终止,于是IE9显示请求“已挂起”、“已终止”。具体深层次的原因不清楚,下面是个人一些猜想和解释:
1、 JS代码只有加载才会被执行,而触发js加载的正是html/jsp页面的显示。所以,我觉得Html/jsp就是js的执行环境。如果js还没有执行完,页面关闭的话,后续js代不会再执行。测试代码如下:
  1. <head>  
  2.  <script type='text/javascript'>  
  3.  function test()  
  4.  {  
  5.   alert(1111);  
  6.   window.opener = "";  
  7.   window.open("","_self");  
  8.   window.close();  
  9.   alert("我不会在执行了,因为页面已经关闭。");  
  10.   //setTimeout('callBack( )', 3000)  
  11.  }  
  12.  </script>  
  13. </head>  
  14. <body>  
  15.  <input id="button_-12你" type="button" value="testRight" onclick="test();">  
  16. </body>  
<head>
 <script type='text/javascript'>
 function test()
 {
  alert(1111);
  window.opener = "";
  window.open("","_self");
  window.close();
  alert("我不会在执行了,因为页面已经关闭。");
  //setTimeout('callBack( )', 3000)
 }
 </script>
</head>
<body>
 <input id="button_-12你" type="button" value="testRight" onclick="test();">
</body>
个人感觉,可能是jquery拼post的请求体,会相对比较耗时,还没有执行完毕。此时页面关闭,JS终止了执行,浏览器发送了1个不完全的HTTP请求(没有附上请求体)。  这是个人的猜测,大家有自己见解的,欢迎指教。基于这个结论,我们将POST请求,改成Get请求,虽然IE9显示的还是请求终止,但是服务端能够收到请求的参数值了。
原文地址:https://www.cnblogs.com/firstdream/p/7402953.html