-1

I created this html:

<!DOCTYPE html>
<html lang="en" xmlns:https="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Upload Test</title>
</head>
<body>
    <form action="http://localhost:8887/upload/" method="post">
        <label class="btn btn-default btn-file">Browse
            <input type="file" class="hidden"/>
        </label>
        <br>
        <input class="btn btn-default" type="submit">
    </form>
</body>
</html>

So I'm trying to upload data from front end to back end. On back end side I'm using this code:

from flask import Flask
from flask import request

app = Flask(__name__)


    @app.route('/upload/', methods=['POST', 'GET'])
    def upload():
        print(request.files)
        return 'hey'

    if __name__ == '__main__':
        app.run('0.0.0.0', 8887)

The result of the line print(request.files) is always

ImmutableMultiDict([])

I can't understand where is my mistake ?

faoxis
  • 1,912
  • 5
  • 16
  • 31
  • uploading files is not just a regular request. Have you looked at the documentation for uploading files? http://flask.pocoo.org/docs/0.12/patterns/fileuploads/ – Craicerjack Jan 24 '17 at 12:40
  • @Craicerjack yeah, but what's the difference ? If I add `enctype=multipart/form-data` it won't work anyway. – faoxis Jan 24 '17 at 12:44
  • Compare your code to the code in the docs and youll see theres quite a bit of difference. There is also a flask plugin for file uploads - http://pythonhosted.org/Flask-Uploads/. Other than that I dont see what you think is a mistake, a file upload isnt going to print out all the data thats in the file because its a file and not data as it might normally be. I presume its printing out `ImmutableMultiDict([])` because thats how its storing it – Craicerjack Jan 24 '17 at 12:55

1 Answers1

1

I'm no flask developer per se but as @Craicerjack already said, all you need to do a form upload is:

  1. A tag is marked with enctype=multipart/form-data and an <input type=file> is placed in that form.
  2. The application accesses the file from the files dictionary on the request object.
  3. Use the save() method of the file to save the file permanently somewhere on the filesystem.

The multipart/form-data makes a lot of difference because it explicitly says that:

  1. There are going to be different mime-types in the request.

  2. Your form data should not be encoded (if memory serves the other values are application/x-www-form-urlencoded and text/plain).

Why the multipar/form-data? So the client (a.k.a browser) sends a multipart request that looks something like this

MIME-Version: 1.0
Content-Type: multipart/form-data;
boundary="----=_NextPart_000_0004_01D270B5.6F278C60"
my_post_variable = value
------=_NextPart_000_0004_01D270B5.6F278C60
Content-Type: octet-stream
3434352345345341223423

and the uploaded file goes after the ------=_NextPart_000_0004_01D270B5.6F278C60.

Now, after all that explaining you should add the enctype=multipart/form-data to your form and remove the GET method from the route and that should get your upload going.

yorodm
  • 4,359
  • 24
  • 32