499错误码,client closed request,通常表示客户端关闭了连接,在服务器完全接收请求之前,客户端已经中断了连接。
省流:前端发起请求,前后端建立了连接后,由于传输时间太长,超过了前端设置的超时时间后,前端报错timeout并取消请求,后端提示499client closed request。
什么情况下遇到的499?
实现了一个前端上传文件,后端保存到数据库的功能。前端使用el-upload选中文件后,触发change事件,通过change事件来调用后端保存二进制文件的接口。
某次当选取的文件较大时,在一定时间后,前端报错timeout,ngnix提示499错误。
为什么会遇到499?
超时时间设置得太短,以至于在服务器开始处理请求之前,客户端就因为超时而关闭了连接。在axios配置中修改timeout时间可以解决这个问题。
当文件较大时,上传所需的时间自然会更长。如果设置的超时时间(timeout)较短,而文件上传所需时间超过了这个阈值,那么就会触发超时。
建立连接后,文件传输的时长超过了timeout,由于文件还没完全传输,后端不会给出返回信息,此时前端取消请求,因此会报client closed request。
为什么浏览器控的network中没有后端返回的接口响应?
一开始我也很疑惑,为什么network中并没有接口的响应,后端那边也没有提示该接口被触发。既然都没有响应,那又何来的client closed request?后端甚至“不知道”有request。
其实不然。
上传文件时,客户端(即你的浏览器或前端应用)会尝试与服务器建立TCP连接。这是通过TCP握手(three-way handshake)完成的,确保双方都能发送和接收数据。
el-upload组件在上传文件时,实际上是封装了底层的HTTP请求(通常是通过XMLHttpRequest或者Fetch API)。当用户选择了文件并点击上传后,el-upload会发起一个POST请求到服务器,请求的body中包含了文件数据。
一旦连接建立,客户端就会通过这个连接发送HTTP请求。这个请求包括了请求行、请求头,以及请求体(在POST请求中,这通常是你要上传的文件数据)。
接下来服务器开始接收这个请求,首先处理请求行和请求头部,然后开始接收请求体(文件数据)。
接口并没有响应通常指的是服务器还没有完成对整个请求的处理,并给出一个HTTP响应(如200 OK或其他状态码)。但是,服务器还没有完成处理并发送响应,并不意味着它没有接收到请求。
这里是前后端已经建立了连接,但是在请求体里的文件太大,导致传输时间超过了设置的timeout,这时前端取消了请求,因此后端会报499。
499和HTTP的4xx有什么关系?
状态码499是一个非标准的HTTP状态码,它表示服务器成功处理了请求,但在返回响应之前,客户端主动关闭了连接。
状态码499的起源可以追溯到Nginx服务器,并且在Nginx的日志中用于指示当连接被客户端关闭时,服务器仍在处理请求,导致服务器无法发送状态码回客户端。
HTTP的4XX状态码属于客户端错误类别,表示请求包含语法错误或无法完成请求。状态码499虽然是非标准的,但按照其含义(客户端主动关闭连接),它可以被视为与4XX状态码在分类上有一定的相似性,即都涉及到客户端的行为或错误。
镜像问题:network error
有时类似的情况是后端报错network error,而不是前端报错timeout。
这几乎是同一情况的一体两面,当代理服务的配置中,把超时时长或者文件大小设置得过小时,会报错network error。
例如,当前端超时时长设置为10min,后端设置超时时长为5min,当5分钟后,前端依然在进行文件传输,但是后端设置的已经超时,此时前端会提示后端返回的错误network error,而不是timeout。
这个也是在项目中实际遇到的,一时没反应过来也是超时的错误,提醒一下。