我想通过使用UI的前端Web技术来构建一个应用程序(本地的,而不是在线的),该应用程序仅显示PDF,并具有一些文本字段供用户填写当前的他们正在查看的PDF,然后用户可以将其注释和文件路径以CSV文件格式导出到文档。
comment about file, some more notes, C:\somefolder\doc1.pdf
comment about file, some more notes, C:\somefolder\doc2.pdf
我的第一个问题是JavaScript无法访问本地文件系统,因此我使用了一个文件上载表单,除了文件路径显示为blob文件路径而不是实际的系统文件路径之外,它都可以正常工作。除此之外,我的“应用程序”按预期工作。
我去学习了Flask,希望将python用于后端,该方法非常有用,除了当我在Chrome的'src'属性中将文件路径传递到pdf C:\SomeFolder\doc1.pdf
时,访问本地文件。所以我要回头了!
如何通过本地文件访问来构建此应用程序?
答案 0 :(得分:0)
假设您正在通过http://localhost:8080/page
或类似的方式访问页面,则应该通过该方法来提供内容。实际上,不是将文件作为本地文件系统上的路径提供服务,而是创建应用程序路由并将其与处理程序关联,而不是从本地文件系统中检索适当的PDF,然后将包含Content-Type: application/pdf
的响应发送回HTTP响应标头和响应正文中PDF文件的字节。
为避免重复别人描述的方法的解决方案,我建议您看看this answer for "Flask handling a PDF as its own page"。
由于从技术上讲,您是从localhost
发回响应-或随其提供的名称-而不是尝试直接从客户端的网页加载本地文件,因此Chrome应该不会抛出任何投诉。
当然,值得注意的是,如果确定要加载的文件不仅仅是学习项目,则应采用最佳实践。在做这种事情的任何合法系统中,都必须对请求的文件进行检查,以确保恶意用户不会滥用应用程序从本地文件系统中泄漏文件,而不是打算提供的文件。 (为此,您通常可能使src
元素包含一个参数,该参数设置为文件的哈希/唯一ID,然后通过某个数据库将该参数映射到文件的正确路径。或者,您可能在src
中使用包含文件名而不包含完整路径的参数,然后检查请求中该参数的用户提供的值是否不包含{{1 }}。)最终,听起来这条警告并不适用于您的情况,但仍会提供此警告,以防将来其他人阅读。
答案 1 :(得分:0)
如果需要访问本地文件,则可以在flask中创建一个端点,以启动文件对话框GUI。这仅适用于您的应用程序在本地托管。您可以使用tkinter
或使用win32ui
的本地Windows API。
假设您使用的是标准Flask格式:
from app import app
@app.route('/file_select', methods=['GET', 'POST'])
def file_select():
from tkinter import Tk
from tkinter.filedialog import askopenfilename
root = Tk()
root.withdraw()
# ensure the file dialog pops to the top window
root.wm_attributes('-topmost', 1)
fname = askopenfilename(parent=root)
return jsonify({'filepath': fname})
或使用win32ui API
@app.route('/file_select', methods=['GET', 'POST'])
def file_select():
import win32ui
winobj = win32ui.CreateFileDialog(1, ".pdf", "", 0,
"PDF Files (*.pdf)|*.pdf|All Files (*.*)|*.*|")
winobj.DoModal()
return jsonify({'filepath': winobj.GetPathName()})
现在,只需添加指向/file_select
路由的按钮,即可通过python本地服务器打开文件对话框,并返回所选文件。