Search code examples
pythondjangohttplib

MultiValueDict is empty when image has loaded


I'm trying to simulate browser work. When I'm sending image from browser I get in request.FILES that

<MultiValueDict: {u'file': [<InMemoryUploadedFile: 1.jpg (image/jpeg)>]}>

If I send image from back end POST request:

import httplib
conn = httplib.HTTPConnection(HOST, PORT)
headers = {"Content-type": "application/x-www-form-urlencoded",      "Accept": 'text/plain', 
"Cookie": cookies, 'X_REQUESTED_WITH': 'XMLHttpRequest'}
conn.request("POST", "/upload/%s" % storyId, open("pictures/1.jpg"), headers)
response = conn.getresponse()  

I get:

<MultiValueDict: {}>

What's wrong?


Solution

  • When you send a file from broswer, the Content Type header is multipart/form-data; not application/x-www-form-urlencoded also there are others changes in the request when you send a file. Take a look, here is how a request headers looks like when you send a file from a browser.

    POST /upload?upload_progress_id=12344 HTTP/1.1
    Host: localhost:3000
    Content-Length: 1325
    Origin: http://localhost:3000
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryePkpFF7tjBAqx29L
    <other headers>
    
    ------WebKitFormBoundaryePkpFF7tjBAqx29L
    Content-Disposition: form-data; name="MAX_FILE_SIZE"
    
    100000
    ------WebKitFormBoundaryePkpFF7tjBAqx29L
    Content-Disposition: form-data; name="uploadedfile"; filename="hello.o"
    Content-Type: application/x-object
    
    <file data>
    ------WebKitFormBoundaryePkpFF7tjBAqx29L--
    

    You can read more here in this stackoverflow answer

    Said that, you aren't "simulating" a browser file request correctly.