Flask使用pdfkit生成PDF报错ProtocolUnknownError如何处理?
报错原因
核心是底层依赖的wkhtmltopdf工具在处理你传入的HTML字符串时触发了安全策略限制,具体原因两点:
- 你的
pdf_template.html模板中使用了相对路径引用的静态资源(图片、CSS、字体等),wkhtmltopdf默认禁止加载本地文件资源,会抛出访问阻塞警告。 - 当你传入纯HTML字符串给
pdfkit.from_string时,老版本的wkhtmltopdf会默认使用about:blank作为资源加载的基地址,当前版本的安全规则直接禁止了about协议的访问,最终触发ProtocolUnknownError错误。
另外你代码中make_response(pdf, False)的写法也存在问题,第二个参数是响应状态码,传入False会导致响应头异常。
解决方案
按优先级可以依次尝试以下方法:
- 方法1:添加
wkhtmltopdf运行参数,放开本地资源访问限制
调用pdfkit.from_string时传入配置参数,开启本地文件访问权限,同时指定静态资源所在的目录,示例修改代码:from flask import Flask, render_template, make_response import pdfkit app = Flask(__name__) @app.route('/<Customer_Full_Name>/<Customer_adress>/<customerID_number>/<CurrentDate>/<Digital_Signature>') def pdf_template(Customer_Full_Name, Customer_adress, customerID_number,CurrentDate,Digital_Signature): rendered = render_template('pdf_template.html', Customer_Full_Name=Customer_Full_Name, Customer_adress=Customer_adress, customerID_number=customerID_number, CurrentDate=CurrentDate, Digital_Signature=Digital_Signature ) # 新增pdfkit配置 options = { 'enable-local-file-access': None, # 替换为你自己项目的static文件夹绝对路径 'allow': '/Users/swapnil/Desktop/Clinsj_Certificate/static', } # 调用时传入配置,第二个参数传False代表直接返回PDF二进制内容 pdf = pdfkit.from_string(rendered, False, options=options) # 修正make_response参数,不需要传第二个False response = make_response(pdf) response.headers['Content-Type'] = 'application/pdf' response.headers['Content-Disposition'] = 'inline;filename=output.pdf' return response if __name__ == '__main__': app.run(debug=True) - 方法2:修改模板中静态资源的引用方式,使用绝对HTTP路径
模板中所有静态资源(图片、CSS等)的引用都使用带域名的绝对路径,Flask模板中可以用url_for的_external=True参数生成,示例:
这种方式让<!-- 原来的相对路径写法 --> <!-- <link rel="stylesheet" href="/static/style.css"> --> <!-- 修改后的绝对路径写法 --> <link rel="stylesheet" href="{{ url_for('static', filename='style.css', _external=True) }}"> <img src="{{ url_for('static', filename='logo.png', _external=True) }}">wkhtmltopdf直接通过HTTP协议加载资源,完全规避本地文件访问和about:blank协议的问题。 - 方法3:升级
wkhtmltopdf版本
0.12.5及更早版本的wkhtmltopdf对HTML字符串的基地址处理存在已知bug,升级到0.12.6及以上稳定版本即可修复该问题。
内容的提问来源于stack exchange,提问作者Bunny
相关产品推荐
相关产品推荐

