我使用一个jQuery 1.8.2 $ .ajax调用POST数据到服务器端点来更新数据。这工作正常,除了在一个页面上,其中AJAX POST触发新的NTLM协商。在Chrome,IE和Firefox中也会出现同样的问题。虽然问题在所有的浏览器是相同的,它表现在自己有点不同的方式:
> Firefox:从服务器接收到401 Challenge响应,并打开一个用户名/密码对话框,要求在无限循环中输入凭据。取消凭据检查将导致请求失败并显示未经授权的响应。
> IE:服务器无响应,请求状态在网络监视器中显示为“(中止)”
> Chrome:服务器没有响应,请求状态在网络监视器中显示“(失败)”。
核心问题似乎是Connection:keep-alive头没有与有问题的AJAX请求一起发送,但在其他情况下。但是,底层JavaScript代码几乎相同,并且AJAX在也设置为使用Windows身份验证的开发环境中正确调用函数。
此外,尝试在beforeSend回调中设置连接请求标头没有任何效果。
任何洞察问题的根源,或隔离两个AJAX POST之间存在的任何差异的方式是最感谢。
工作代码和请求标头
$.ajax({ url: url,type: "POST",data: $("#myForm").serialize(),cache: false,success: function (response) { } }); Accept:*/* Accept-Encoding:gzip,deflate Accept-Language:en-US,en;q=0.8 Connection:keep-alive Content-Length:621 Content-Type:application/x-www-form-urlencoded; charset=UTF-8 Host:www.xxx.yyy.zzz Origin:http://www.xxx.yyy.zzz Referer:http://www.xxx.yyy.zzz/app/resource/path User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/42.0.2311.135 Safari/537.36 X-Requested-With:XMLHttpRequest
失败代码和请求标头
$.ajax({ url: url,data: data,success: function (data,status,xhr) { } }); WARN: Provisional headers are shown Accept:*/* Content-Type:application/x-www-form-urlencoded; charset=UTF-8 Origin:http://www.xxx.yyy.zzz Referer:http://www.xxx.yyy.zzz/app/resource/item/1 User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/42.0.2311.135 Safari/537.36 X-Requested-With:XMLHttpRequest
我也看过Chrome chrome:// net-internals /#events查看器中的网络过程。这是来自失败请求的事件日志,它在偏离成功的请求的点。在失败的请求获得“HTTP / 1.1 401未授权”的情况下,成功的请求获得“HTTP / 1.1 200 OK”响应,大概是由于存在Connection:keep-alive头。
2303: URL_REQUEST Start Time: 2015-04-28 13:53:41.788 t=14736 [st= 0] +REQUEST_ALIVE [dt=71] t=14736 [st= 0] URL_REQUEST_DELEGATE [dt=0] t=14736 [st= 0] +URL_REQUEST_START_JOB [dt=70] --> load_flags = 2688000 (BYPASS_DATA_REDUCTION_PROXY | MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VERIFY_EV_CERT) --> method = "POST" --> priority = "LOW" --> upload_id = "0" --> url = "http://..." t=14736 [st= 0] URL_REQUEST_DELEGATE [dt=0] t=14736 [st= 0] HTTP_CACHE_GET_BACKEND [dt=0] t=14736 [st= 0] URL_REQUEST_DELEGATE [dt=0] t=14736 [st= 0] +HTTP_STREAM_REQUEST [dt=0] t=14736 [st= 0] HTTP_STREAM_REQUEST_BOUND_TO_JOB --> source_dependency = 2305 (HTTP_STREAM_JOB) t=14736 [st= 0] -HTTP_STREAM_REQUEST t=14736 [st= 0] +HTTP_TRANSACTION_SEND_REQUEST [dt=0] t=14736 [st= 0] HTTP_TRANSACTION_SEND_REQUEST_HEADERS --> POST ... HTTP/1.1 Host: www.xxx.yyy.zzz Connection: keep-alive Content-Length: 105 Accept: */* Origin: http://www.xxx.yyy.zzz User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/42.0.2311.135 Safari/537.36 X-Requested-With: XMLHttpRequest Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Referer: http://www.xxx.yyy.zzz/app/resource/item/1 Accept-Encoding: gzip,deflate Accept-Language: en-US,en;q=0.8 t=14736 [st= 0] HTTP_TRANSACTION_SEND_REQUEST_BODY --> did_merge = true --> is_chunked = false --> length = 105 t=14736 [st= 0] -HTTP_TRANSACTION_SEND_REQUEST t=14736 [st= 0] +HTTP_TRANSACTION_READ_HEADERS [dt=0] t=14736 [st= 0] HTTP_STREAM_PARSER_READ_HEADERS [dt=0] t=14736 [st= 0] HTTP_TRANSACTION_READ_RESPONSE_HEADERS --> HTTP/1.1 401 Unauthorized Content-Type: text/html Server: Microsoft-IIS/7.5 WWW-Authenticate: Negotiate WWW-Authenticate: NTLM X-Powered-By: ASP.NET X-UA-Compatible: IE=9 Date: Tue,28 Apr 2015 18:53:41 GMT Content-Length: 1293
编辑
使用来自控制台的不同请求来回答下面的结果表(在Chrome下)。当前基本URL是http:// IPAddress
/ app / topic / item,并且所有测试只需执行$ .ajax({url:url,type:’POST’})
+--------------------------------------+----------------------------+ | URL | Response | +--------------------------------------+----------------------------+ | http://IP/app/topic/item/1/subitem/1 | net::ERR_INVALID_HANDLE | | //IP/app/topic/item/1/subitem/1 | net::ERR_INVALID_HANDLE | | /app/topic/item/1/subitem/1 | net::ERR_INVALID_HANDLE | | 1/subitem/1 | net::ERR_INVALID_HANDLE | | 1/foo | 404 (Not Found) [expected] | | 1 | 302 (Redirect) [expected] | +--------------------------------------+----------------------------+
因为错误只影响一个控制器中的POST操作方法的一个子集,我最初认为这是一个服务器端问题,但是在发现缺少的连接头的问题后,它实际上似乎是一个客户端问题。究竟如何触发的问题仍然是我的一个谜。
我也验证了工作页面和有问题的页面的响应标头是相同的。最相关的是,在两种情况下都会返回Persistent-Auth:true头。