Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload data URL to Django server

I am trying to do this in Django (async upload a canvas as an image file). I'm using (a slightly modified version of) the javascript found in the demo, which rolls its own XHRHttpRequest, but I fail to find any evidence of the upload on the server side.

The canvas data is being extracted like this:

img_data = canvas.toDataURL('image/jpeg').replace("data:image/jpeg;base64,", "");

This is the xhr header:

xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=multipartformboundary1352769538973');

This is the POST content:

--multipartformboundary1352769538973
Content-Disposition: form-data; name="user_file"; filename="test.jpeg"
Content-Type: application/octet-stream

/9j/4AAQSkZJRgABAgAAAQABAAD/2wCEAAUDAwUHD...snipping image data...
AJRRRQAUtJS018gA/9k=
--multipartformboundary1352769538973
Content-Disposition: form-data; name="username"


--multipartformboundary1352769538973
Content-Disposition: form-data; name="challenge"


--multipartformboundary1352769538973
Content-Disposition: form-data; name="galleryPath"


--multipartformboundary1352769538973--

When I ask Django to show me the request object it sees, this is what I get:

<WSGIRequest
path:/samlite/save_frame,
GET:<QueryDict: {}>,
POST:<QueryDict: {u'username': [u''], u'challenge': [u''], u'galleryPath': [u'']}>,
COOKIES:{},
META:{'ARCHFLAGS': '-arch i386',
 'Apple_PubSub_Socket_Render': '/tmp/launch-wL0OpX/Render',
 'Apple_Ubiquity_Message': '/tmp/launch-ox20mG/Apple_Ubiquity_Message',
 'COMMAND_MODE': 'unix2003',
 'CONTENT_LENGTH': '34323',
 'CONTENT_TYPE': 'multipart/form-data; boundary=multipartformboundary1352769538973',
 'DISPLAY': '/tmp/launch-KzsfWx/org.x:0',
 'DJANGO_SETTINGS_MODULE': 'simsam.settings',
 'DYLD_LIBRARY_PATH': '/Applications/bitnami-djangostack/apps/django/lib/python2.7/site-packages:/Applications/bitnami-djangostack/apps/django/lib/python2.7/site-packages:/Applications/bitnami-djangostack/python/lib:/Applications/bitnami-djangostack/mysql/lib:/Applications/bitnami-djangostack/sqlite/lib:/Applications/bitnami-djangostack/apache2/lib:/Applications/bitnami-djangostack/common/lib:',
 'GATEWAY_INTERFACE': 'CGI/1.1',
 'HOME': '/Users/chris',
 'HTTP_ACCEPT': 'text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1',
 'HTTP_ACCEPT_ENCODING': 'gzip, deflate',
 'HTTP_ACCEPT_LANGUAGE': 'en,en-US;q=0.9,ja;q=0.8,fr;q=0.7,de;q=0.6,es;q=0.5,it;q=0.4,pt;q=0.3,pt-PT;q=0.2,nl;q=0.1',
 'HTTP_CONNECTION': 'Keep-Alive',
 'HTTP_HOST': 'localhost:8000',
 'HTTP_REFERER': 'http://localhost:8000/samlite/',
 'HTTP_USER_AGENT': 'Opera/9.80 (Macintosh; Intel Mac OS X 10.7.5) Presto/2.12.388 Version/12.10',
 'LANG': 'en_US.UTF-8',
 ...less interesting stuff snipped...
}>

So the normal POST key/value pairs are getting through, but based on this, I expected to see a response.FILES dictionary. Can anyone point me in the right direction?

like image 759
Chris Avatar asked Nov 13 '12 01:11

Chris


2 Answers

Turns out the whole thing was vastly easier if I just POSTed canvas.toDataURL(), trimmed the string as above, and did this on the server:

img_data = img_string.decode("base64")
img_file = open("photo.jpg", "wb")
img_file.write(img_data)
img_file.close()

Edit per Sean's comment

What I sent in the POST was just the base64 data part, which means remove these leading characters from the result of toDataURL():

data:image/jpeg;base64,

This could be done client side or server side, the point is that you need to drop that stuff before you decode the base64 characters to binary and write the image file.

like image 62
Chris Avatar answered Sep 25 '22 00:09

Chris


Django doesn't include the FILES dictionary in the repr() output. Try accessing it anyway:

print request.FILES

In the Django source, you can see that path, GET, POST, COOKIES, and META are included, but not FILES.

like image 34
Brian Rue Avatar answered Sep 22 '22 00:09

Brian Rue