今天遇到了一个诡异的问题,前端同学说测试环境一个h5页面请求时不时的抽疯报400 bad request 问题

问题的症状是这样的:

  • 在chrome上该页面可以百分百正常访问,抽疯问题只发生在Safari上
  • 问题不是必现,有时可以得到请求结果,有时得不到
  • 除了400的告错,没有任何的提示

nginx 400的常见原因

  • URI没有传递host,这一点在做代理时比较容易出现,比如有的nginx将请求转发时,host没有正确配置或采用通配符(wildcard)时,host值传递到真正的服务器上可能出错,导致400错误
  • 请求头过大,但一般client_header_buffer_size的默认值是1K,一般的请求没有理由出现这么大的请求头的

首先查看nginx日志,发现只有access log里有400日志,没有其他错误日志或提示,因为问题不是必现,所以感觉很诡异

打开Safari开发工具栏,发现打开h5页面时会有多个请求,其中一个请求(打点请求)因为后端没有配置,所以一直是400状态,但因为有时页面能正常显示,并且chrome上这个错误请求也是存在的,所以没有在意的,所以一直把注意力放在Safari的cookie及请求体是否过大,nginx是否配置了某些与Safari不兼容的选项等问题上

由于Apple的闭环系统,网上实在搜不到有用的信息,所以想用排除法了,先让页面的其他请求都能正常访问,看是否有相互影响,于是配置nginx让对 打点请求 返回200,奇迹出现了,该页面可以正常显示了,问题不在复现

分析:

a) 页面无法加载原因

因为该打点请求的400,导致了后续请求的400

b) 为什么有时候又是正常的

跟前端同学确认,请求的发送无严格的先后顺序,所以如果请求在打点请求之前发送,则会先拿到200结果,不影响页面加载

c) 为什么后端报404,nginx报400错误

这个是比较诡异的地方,后面重新发布了一次后就报正常的404了

d) 为什么a请求的400(后端其实返回404, nginx返回400)会导致b请求的400

稍晚些时候想要复现研究时,发现因为nginx报了404错误导致问题不再复现了,不过可以确定的是因为a请求的400错误导致了后续请求的直接400错误, 鉴于chrome没有这种错误,所以怀疑是否Safari在对同一个host的请求采用了pipline技术,多个http请求复用同一个TCP连接,导致某个请求出错时引发了这种崩溃效果,还请有知晓的大神帮忙解读

⤧  Next post 关于调用微信支付API需要指定IPV4 ⤧  Previous post 关于nginx中host, server_name, http_host的区别