Flask使用send_file发送pikepdf生成的BytesIO流PDF出现content length不匹配
问题根因与修复方法
核心报错原因
ERR_CONTENT_LENGTH_MISMATCH报错是因为你将PDF内容写入io.BytesIO流后,流的文件指针停在了内容末尾,send_file方法读取流时从指针当前位置开始读,无法获取到实际的PDF内容,最终返回的内容长度和响应头中预先计算的内容长度不一致,触发报错。
其他需要修复的代码问题
- 缺少
io、Pdf对应依赖库、request对象的导入声明 - Flask 路由函数默认不接收
request传参,需要单独导入全局request对象使用 send_file本身已经是合法的Flask响应对象,不需要额外用make_response包裹,多余的包裹操作可能导致响应头计算异常- OPTIONS响应中声明允许的请求方法是POST,但路由没有配置支持POST方法,可能导致后续跨域请求被拦截
修复后完整代码
from flask import Flask, send_file, request import io # 请根据你实际使用的PDF库调整对应导入语句,此处示例为PyPDF2的导入写法 from PyPDF2 import PdfReader as Pdf app = Flask(__name__) # 配置路由支持GET、POST、OPTIONS三种请求方法 @app.route("/", methods=["GET", "POST", "OPTIONS"]) def get_pdf(): # 处理预检请求 if request.method == 'OPTIONS': headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'POST,GET', 'Access-Control-Allow-Headers': 'Content-Type', 'Access-Control-Max-Age': '3600' } return ('', 204, headers) pdf = Pdf.open('test.pdf') file = io.BytesIO() pdf.save(file) # 将流的指针重置到起始位置,让send_file可以读取到完整内容 file.seek(0) response = send_file(file, download_name="project_pdf.pdf", mimetype='application/pdf', as_attachment=True) response.headers.set('Access-Control-Allow-Origin', '*') return response if __name__ == "__main__": app.run(debug=True)
内容的提问来源于stack exchange,提问作者Johann Süß
相关产品推荐
相关产品推荐

