如何在Django中展示MySQL数据库Blob存储的PDF文件?
搞定MySQL Blob存储的PDF展示问题!
你现在用临时文件传递PDF的方式可以简化不少——直接让后端把数据库里的Blob二进制数据以正确的HTTP响应返回给前端,浏览器就能原生渲染PDF了,既省事儿又避免临时文件的管理麻烦。下面分后端处理和前端展示两部分给你具体方案:
后端:读取Blob并返回PDF响应
看你上传代码里用了request.FILES,大概率是Flask或Django这类Python框架,我分别给你写两种场景下的代码:
Flask版本
from flask import Response, get_db # get_db替换成你自己获取数据库连接的方法 @app.route('/view-pdf/<int:report_id>') def view_pdf(report_id): # 先做权限校验!比如检查当前登录用户是否有权限看这个PDF # if not has_permission(current_user, report_id): # return "无权限访问", 403 db = get_db() fcursor = db.cursor() fcursor.execute("SELECT DOC FROM REPORTS WHERE id = %s", (report_id,)) result = fcursor.fetchone() fcursor.close() db.close() if not result: return "该PDF不存在", 404 pdf_data = result[0] # 返回带正确头的响应,让浏览器识别是PDF并直接展示 return Response( pdf_data, mimetype='application/pdf', headers={ 'Content-Disposition': 'inline; filename="report_{}.pdf"'.format(report_id) } )
Django版本
from django.http import HttpResponse from django.db import connection def view_pdf(request, report_id): # 权限校验不能少! # if not request.user.has_perm('view_report', report_id): # return HttpResponse("无权限访问", status=403) with connection.cursor() as cursor: cursor.execute("SELECT DOC FROM REPORTS WHERE id = %s", [report_id]) result = cursor.fetchone() if not result: return HttpResponse("该PDF不存在", status=404) pdf_data = result[0] response = HttpResponse(pdf_data, content_type='application/pdf') response['Content-Disposition'] = 'inline; filename="report_{}.pdf"'.format(report_id) return response
这里的核心是设置两个HTTP头:
mimetype(或content_type)设为application/pdf,告诉浏览器这是PDF文件Content-Disposition用inline表示在浏览器内直接打开,而不是触发下载;如果想保留下载选项,也可以留空或者改成attachment(不过你要的是展示,inline更合适)
前端:模板里嵌入PDF展示
后端接口写好后,前端模板里用<iframe>、<embed>或者<object>标签加载就行,<iframe>的兼容性最好:
Flask Jinja2模板示例
<iframe src="{{ url_for('view_pdf', report_id=report.id) }}" width="100%" height="800px" frameborder="0"> 你的浏览器不支持PDF预览,请<a href="{{ url_for('view_pdf', report_id=report.id) }}">点击下载</a> </iframe>
Django模板示例
<iframe src="{% url 'view_pdf' report.id %}" width="100%" height="800px" frameborder="0"> 你的浏览器不支持PDF预览,请<a href="{% url 'view_pdf' report.id %}">点击下载</a> </iframe>
为啥不推荐临时文件?
之前的临时文件方案有几个坑:
- 要额外写代码创建、管理、清理临时文件,服务器崩溃时容易留残留文件
- 多用户同时访问时可能出现文件竞争的问题
- 直接返回二进制数据流更高效,减少磁盘IO操作
额外提醒
- 权限校验一定要加:在
view_pdf函数开头必须检查当前用户是否有权限查看该PDF,别让任何人都能通过ID访问 - 如果PDF文件很大(比如超过10MB),存在Blob里会拖慢数据库性能,这时建议把大文件存在本地文件系统或对象存储,数据库只存文件路径,读写效率会高很多
内容的提问来源于stack exchange,提问作者user9534288
相关产品推荐
相关产品推荐

