HTTP 协议中,从语义上讲, GET 请求一般是获取服务器端的资源,不会对服务器数据造成副作用,可简单理解为一种“读”操作;而 POST 请求多用于更改(增、删、改)服务器上的资源,会产生一定的副作用。
所以,这样看起来,浏览器是不是就不会因为网络原因啥的自动重发 POST 请求吧?实际上是这样么?
起因
今日开发一个需求,页面点击事件后,调用后台逻辑,需要先从资金到账表扣减资金,将扣减的资金写入共保备付金表,然后根据备付金表进行收费操作,因为收费记录很多(上万条收费记录)。导致收费时间需要十几分钟。每次页面提交一次请求。但后台处理时收了两次费用,显然重复收费了。
分析
1、开始分析时,通过查询后台日志,发现有两次前端页面的提交记录。认为是用户操作时,重新刷新了页面,重新进行了收费
通过后来的宣导后,用户很小心的操作,之操作了一次。还是出现重复收费了(崩溃)。
2、这时就猜测考虑是不是一业务处理逻辑太久了,导致浏览器长时间没有接受到后台的返回结果,重复提交了记录。
3、后台通过网上搜索原因,发现确实是重复发送请求了,但并不是浏览器长时间没有收到后台返回结果,而是我们weblogic 服务器有个600秒的超时控制,但超过600秒时,就中断了请求,这时浏览器就重新发起了请求了。
重新发起请求原因
If an HTTP/1.1 client sends a request which includes a request body, but which does not include an Expect request-header field with the "100-continue" expectation, and if the client is not directly connected to an HTTP/1.1 origin server, and if the client sees the connection close before receiving any status from the server, the client SHOULD retry the request.
大致意思就是说,如果发送一个请求到服务器端,该请求有请求体,但是请求头里面不包含“ 100-continue ”这种东西,并且客户端没有直接连接到原始的 HTTP/1.1 服务器,此时,如果客户端在接收到服务器发送的 HTTP 状态之前发现服务器主动关掉连接,那么客户端应该重试请求。
那看起来好像就是服务器端主动关掉了连接,导致浏览器重新发送请求了。