HTTP status Code 412 未满足前提条件的解决方法之一

最近网站老是报告错误.  ajax返回状态为 error 思来想去不知道为啥.

后来跟踪了下,发现是在请求某个页面的时候会返回412错误. 

而这个页面的请求是通过jquery  的 $("#panel").load("http://****"); 方法去请求的.


各种百度无果.. 

只得到一个结果. 


412 未满足前提条件
前提条件失败 
在服务器上测试前提条件时,部分请求标题字段中所给定的前提条件估计为FALSE。客户机将前提条件放置在当前资源 metainformation(标题字段数据)中,以防止所请求的方法被误用到其他资源。 
如果问题依然存在,请与 Web 服务器的管理员联系。 



用httpfiddle 跟踪后发现,此请求内容如下:


POST http://****/widget/ZhuCePanel.html HTTP/1.1
Host: pay.*****.cn
Connection: keep-alive
X-Requested-With: XMLHttpRequest
If-Modified-Since: Fri, 19 Feb 2016 02:53:00 GMT
Accept-Encoding: gzip, deflate
If-None-Match: "201827-95d-52c1694befb00"
Accept-Language: zh-cn
Accept: text/html, */*; q=0.01
Origin: http://**
Content-Length: 0
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12F70 Safari/600.1.4
Referer: http://****/GeRenZhongXin.html
Connection: keep-alive
Cookie: access_token=f33c641f-0ff9-40d5-bd29-b61643745f2e;</span>

其中各个KEY的含义都了解,只有

If-None-Match

ETags

两个参数比较陌生. 百度了下, 

google告诉网站站长:您的网络服务器支持 If-Modified-Since HTTP 标头。通过该功能,您的网络服务器可以告诉 Google 自上次抓取您的网站以来,内容是否已发生变化。该功能可以节省您的带宽和开销。
我们来看一下网上对HTTP 头:Last-Modified 与 If-Modified-Since的介绍。(看了两个博客,都没有图片。)
简单的说,Last-Modified 与If-Modified-Since 都是用于记录页面最后修改时间的 HTTP 头信息,只是 Last-Modified 是由服务器往客户端发送的 HTTP 头,而 If-Modified-Since 则是由客户端往服务器发送的头,可 以看到,再次请求本地存在的 cache 页面时,客户端会通过 If-Modified-Since 头将先前服务器端发过来的 Last-Modified 最后修改时间戳发送回去,这是为了让服务器端进行验证,通过这个时间戳判断客户端的页面是否是最新的,如果不是最新的,则返回新的内容,如果是最新的,则 返回 304 告诉客户端其本地 cache 的页面是最新的,于是客户端就可以直接从本地加载页面了,这样在网络上传输的数据就会大大减少,同时也减轻了服务器的负担。想要详细查看 HTTP 头信息,可以在 Firefox 中安装 LiveHTTPHeaders 插件,安装完成之后按 Alt+L 就可以在 Sidebar 中看到了。
ETags和If-None-Match是一种常用的判断资源是否改变的方法。类似于Last-Modified和HTTP-IF-MODIFIED-SINCE。但是有所不同的是Last-Modified和HTTP-IF-MODIFIED-SINCE只判断资源的最后修改时间,而ETags和If-None-Match可以是资源任何的任何属性,不如资源的MD5等。
ETags和If-None-Match的工作原理是在HTTP Response中添加ETags信息。当客户端再次请求该资源时,将在HTTP Request中加入If-None-Match信息(ETags的值)。如果服务器验证资源的ETags没有改变(该资源没有改变),将返回一个304状态;否则,服务器将返回200状态,并返回该资源和新的ETags。
 

牵扯到412状态的问题描述.  直觉告诉我,应该就是这个If-None-Match 参数     导致服务器端取客户端的 If-None-Match 的数值不匹配,或者取不到造成的


不匹配应该不太可能,但是也无法知道.到底批不匹配.服务器端的值是多少我们也不清楚.

我再看了下其它请求,也有这个If-None-Match 参数,其它请求都能取到.. 为啥,这个特定的请求取不到呢?

经过我多次尝试,突然间发现, 红色的412状态的 请求好像都是POST请求嘛....

于是我猜测,服务器默认只能处理GET的缓存.


可为啥 
$("#panel").load("http://****");

会用POST请求呢? 不是默认GET请求吗?  想了半天突然间想起来了. 我好像在 

$.ajaxSetup({
    success: function (data) {
        try { $("body").hideLoading(); } catch (ex) { }
    },
    type:"POST",
    error: function (xhr, status, e) {

        try { $("body").hideLoading(); } catch (ex) { }
        console.error(xhr.responseText);

        if(status == "timeout"){
            alert("连接服务器超时.");
        }else if(status == "error"){
        	
        	if(! confirm("连接服务器error")){
        		
        		alert(
	        		"\nxhrstatus="+ xhr.status +
	        		"\n readyState="+ xhr.readyState + 
	        		"\n status="+ status +
	        		"\n responseText=" + xhr.responseText
        		);
        	}
            
        }else if(status == "notmodified"){
            alert("连接服务器异常notmodified"); 
        }else if(status == "parsererror"){
            alert("解析服务器数据发生异常."); 
        }
    },
    complete: function (xhr, status) {
        try { $("body").hideLoading(); } catch (ex) { }
    },
    beforeSend: function (xhr) {
        //if(xhr.notloading){
            try { $("body").showLoading(); } catch (ex) { }
        //}
    }
});


重点在 type:"POST"  上. 这个设置把整个ajax请求都改成POST了.

然后我把这个去掉以后,就彻底解决了. 


从这个问题上学到以下几个知识.

1.   304状态判断  靠的是 If-None-Match 参数,    If-None-Match 值变了,第二次请求就会刷新.否则使用缓存的.好像还有其它几个参数.也可以的

2.   服务器默认只缓存GET请求.  也就是说GET请求可以缓存,  我们的数据请求不应该用GET请求.而应该用POST.

3.   $.ajaxSetup 影响 $.load() 方法.

4.   412 错误是因为无法取到POST过来的If-None-Match 参数而导致的,  改成GET方式 就好了.  


我看到网上有人说把缓存功能禁用就好了, 当然禁用缓存也能解决问题. 不过禁用缓存功能就亏大发了.










412 未满足前提条件
  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值