0

I'd like to build an application (local, not online) by using front-end web technology for the UI, the application simply displays PDFs and has a few text fields for the user to fill in with regards to the current PDF they're viewing, the user can then export their notes and a file path to the document in CSV file format.

comment about file, some more notes, C:\somefolder\doc1.pdf

comment about file, some more notes, C:\somefolder\doc2.pdf

My first issue, JavaScript can't access the local file system, so I used a file upload form which worked except the filepaths were shown as blob filepaths and not the actual system file path. Other than that my "application" worked as intended.

I went and learned Flask in hopes of using python for the back end, which works great except when I pass in the file path to the pdf C:\SomeFolder\doc1.pdf inside the 'src' attribute for an Chrome says it can't access local files. SO I'm back to sqaure one!

How can I go about building this application with local file access?

Ari
  • 5,301
  • 8
  • 46
  • 120

3 Answers3

1

If you need to access the local files, you can create an endpoint in flask that launches a file dialog GUI. This only works because you application is hosted locally. You can use either tkinter or the native windows API using win32ui.

Assuming you are using the standard Flask format:

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})

or using the 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()})

Now just add a button that points to the /file_select route and you will open a file dialog via the python local server and return the selected file.

James
  • 32,991
  • 4
  • 47
  • 70
0

Assuming you are accessing the page via http://localhost:8080/page or something like that, you should serve your content via that approach. Effectively, rather than serving the files as paths on the local file system, you would create an application route and associate it with a handler than retrieves the appropriate PDF from the local filesystem, and then sends back a response containing Content-Type: application/pdf in the HTTP response headers and the bytes of the PDF file in the response body.

To avoid duplicating someone else's solution for the approach described about, I would recommend taking a look at this answer for "Flask handling a PDF as its own page".

Because you are technically sending the response back from localhost -- or whatever name you are serving it with -- rather than trying to load a local file directly from the client's web-page, Chrome shouldn't throw any complaints.

Of course, it's worth noting that best practices should be taken when determining the file to load, if this were going to be anything more than a learning project. In any legitimate system that did this kind of thing, it would be necessary to perform checks on the requested files to ensure a malicious user does not abuse the application to leak files from the local filesystem, beyond those files which are intended to be served. (To that end, you typically might have the src element contain a parameter that is set to the hash/unique ID for the file which is then mapped via some database to the correct path of the file. Alternatively, you might use a param in the src that contains the name of the file without the full path, and then check that the user-provided value for that parameter in the request does not contain any characters outside of a charset like [a-zA-Z0-9_-].) Ultimately, it sounds like this particular warning doesn't apply to your case, but still providing it in case anyone else reads this in the future.

Spencer D
  • 3,376
  • 2
  • 27
  • 43
0

I think mht is exactly what you want. mht is a file extension recongnized by IE. Internally it is an HTML file. IE (only) treats a mht file with the same security restrictions that a exe might have. You could access the file system, delete a file, display a file etc.. It is everything that html/javascript security was trying to prevent. Now that IE has changed significantly I don't know what the support for this is nowadays. I couldn't find a reference page to give you a link, but it is simple enough - just save a html file with an mht extension

user1529413
  • 458
  • 8
  • 19