业务场景
自研影像系统,使用IE处理器打开服务器返回的图片链接时,打开失败,且服务器出现错误日志
2021-05-18 20:11:22.643 [http-nio-8226-exec-10] ERROR c.c.s.impl.ImageViewServiceImpl - java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:351)
at org.apache.catalina.connector.OutputBuffer.appendByteArray(OutputBuffer.java:746)
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:675)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:386)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:364)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96)
at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextServletOutputStream.write(OnCommittedResponseWrapper.java:645)
at org.springframework.security.web.util.OnCommittedResponseWrapper$SaveContextServletOutputStream.write(OnCommittedResponseWrapper.java:645)
at com.chic.service.impl.ImageViewServiceImpl.viewPic(ImageViewServiceImpl.java:91)
at com.chic.controller.image.ImageViewController.viewImage(ImageViewController.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
原因
IE按照响应头的Content-Type去解析图片,然而图片的真正格式与响应头的声明不一致(比如图片实际是jpg,而响应头是 image/png)。当响应头X-Content-Type-Options = nosniff时,会导致IE主动停止解析。
解决方案
/*
设置响应头:默认值是nosniff (禁止资源类型嗅探)
值为nosniff时,如果响应头Content-Type与实际文件类型不一致,浏览器会中断解析,而不是尝试读取文件内容去解析。
例如 图片格式是jpg,返回的Content-Type是image/png,则IE浏览器解析图片会失败。(与浏览器的支持有关,谷歌不会受影响)
因此将此响应头设置为空
*/
response.addHeader("X-Content-Type-Options","");