zoukankan      html  css  js  c++  java
  • chrome 浏览器的预提取资源机制导致的一个请求发送两次的问题以及ClientAbortException异常

    调查一个 pdf 打印报错:

    ExceptionConverter: org.apache.catalina.connector.ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error
    	at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:407)
    	at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480)
    	at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
    	at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:432)
    	at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:420)
    	at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:91)
    	at java.io.BufferedOutputStream.write(Unknown Source)
    	at com.itextpdf.text.pdf.OutputStreamCounter.write(OutputStreamCounter.java:157)
    	at java.io.ByteArrayOutputStream.writeTo(Unknown Source)
    	at com.itextpdf.text.pdf.PdfStream.toPdf(PdfStream.java:353)
    	at com.itextpdf.text.pdf.PdfIndirectObject.writeTo(PdfIndirectObject.java:157)
    	at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:396)
    	at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:376)
    	at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:329)
    	at com.itextpdf.text.pdf.PdfWriter.addToBody(PdfWriter.java:780)
    	at com.itextpdf.text.pdf.TrueTypeFontUnicode.writeFont(TrueTypeFontUnicode.java:385)
    	at com.itextpdf.text.pdf.FontDetails.writeFont(FontDetails.java:274)
    	at com.itextpdf.text.pdf.PdfWriter.addSharedObjectsToBody(PdfWriter.java:1249)
    	at com.itextpdf.text.pdf.PdfWriter.close(PdfWriter.java:1169)
    	at com.itextpdf.text.pdf.PdfDocument.close(PdfDocument.java:780)
    	at com.itextpdf.text.Document.close(Document.java:409)
    

    可以看到 在 调用 pdf 的 Document.close() 方法时,抛出了上诉错误。

    调试之后的原因是,在chrome浏览器中页面上 点击一次 打印,打印 servlet 会执行两次,第一次 可以正常打印,document.close() 可以正常执行,没有报错,可以执行完了之后,servlet又一次执行了!所以在第二次 document.close() 时,报错:

    ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error

    原因是,浏览器已经关闭了连接,所以第二次 向浏览器输出 :

    response.setContentType("application/pdf");

    时,才报错。

    发现只有 chrome才存在这个问题。调查的结果:

    -----------------------------------------------------------------------------------------

    http://blog.lifw.org/post/66162597

    贴下全文:

    chrome等浏览器的预提取资源机制导致的一个请求发送两次的问题以及ClientAbortException异常

    博主在写一篇关于文件下载的博文 http://blog.lifw.org/post/24251622 时,遇到了一个很恶心的问题,现象是我在 chrome 以及 Safari 浏览器地址栏直接输入文件下载链接 localhost:8080/download 时,我的 download 方法被请求了两次,并且第一次抛出如下的 ClientAbortException 异常

    然后 chrome 了很多资料,最后终于找到原因:由于 chrome、Safari 等浏览器为了使网页加载更快,使用了一种叫做预提取资源,以便更快速地加载网页机制,也就是说当你在浏览器中输入 url 后,即便你还没回车发送请求,浏览器也会预先发送请求加载资源,因此每当我在地址栏中输入 url localhost:8080/download 时,浏览器便发送请求到我的 download 方法中,然后我的 download 方法给浏览器返回一个文件下载响应,此时,浏览器一看是文件下载,不能预先加载,因此便主动关闭了链接,便导致了ClientAbortException 异常,然后我回车真正发送了该请求,浏览器便会下载文件,此时没有异常,文件下载成功。综上所诉,便导致 chrome 一个请求发送两次的现象。

     

    网上查找资料的过程中,看到有的人在做计数统计的时候,如果使用 chrome,则每次请求会计数两次,其实也是该问题导致的,因此如果你在开发的过程中,如果莫名其妙的遇到一个请求发送多次的问题,不妨往这方面考虑一下,关闭 chrome 的预提取资源功能测试一下,往往便能解决问题。这个问题非常恶心,并且不易察觉,希望本文能对后来人有所帮助。

     

  • 相关阅读:
    响应式布局,流式布局与固定布局
    垃圾回收机制
    形象讲解时间复杂度
    数据结构和算法简介
    数据结构之栈和队列
    十、str的索引、切片和str常用的操作方法(重点)
    九、基础数类型总览和str、int、bool之间的相互转化
    八、编码的初识和进阶
    七、格式化输出和运算符
    六、while循环
  • 原文地址:https://www.cnblogs.com/digdeep/p/5597936.html
Copyright © 2011-2022 走看看