-
Notifications
You must be signed in to change notification settings - Fork 3
Uploadingscreenshots
HTMLFeedback comes with several ways of uploading rendered screenshots via AJAX. However, not all methods may work client and server side.
Some of the problems there are:
- A few browser support the toBlob() method on a canvas element
- Not all browsers support the BlobBuilder, part of the File API to upload Blobs (like files)
- Most browser support the toDataURL() method on a canvas element, but this returns a string representation of your image encoded in Base64. You cannot post this string to the server and expect it to upload it correctly.
Also, a few browsers do not support the FormData object, part of XHR2. This objects allows the creation of form objects in pure JavaScript.
By default, HTMLFeedback tries to use the best features available, but will fall back on string upload of the image. You can override this settings (see HowToUse), but this may cause incompatibilities for some users.
Since it might be possible that the user is uploading the data as string or as file, you should check it and handle this the right way. Here are two examples (in PHP and Django), both using the same approach: if screenshot not in FILES and screenshot in POST, then convert Base64-String to File.
<?php
$uploadName = 'screenshot';
$uploadTo = dirname(__FILE__) . "/screenshots/";
$filename = md5(mktime()) . ".png";
if (!file_exists($uploadTo)) mkdir($uploadTo);
if (array_key_exists($uploadName, $_FILES)) { // Upload via files
move_uploaded_file($_FILES[$uploadName]['tmp_name'], $uploadTo . $filename);
} elseif (array_key_exists($uploadName, $_POST)) { // Upload via dataURI
$fileData = substr($_POST[$uploadName], strpos($_POST[$uploadName], ",") + 1);
$fileData = base64_decode($fileData);
file_put_contents($uploadTo . $filename, $fileData);
}
echo "ok";
?>
The Django example tries to convert the image data from a string to a SimpleUploadedFile. Then, Django will take care of it like a normal file.
from django.forms import Form, FileField
class UploadFileForm(forms.Form):
screenshot = forms.FileField()
def __init__(self, data=None, files=None, *args, **kwargs):
""" If screenshot has been posted as a string, convert it to an uploaded
file and let Django handle the rest.
"""
if files != None and data != None:
if 'screenshot' not in files and 'screenshot' in data:
from django.core.files.uploadedfile import SimpleUploadedFile
import re
info = re.search(r'data:(.*);base64,(.*)', data['screenshot'])
files[u'screenshot'] = SimpleUploadedFile('blob', info.group(2).decode('base64'), info.group(1))
del data['screenshot']
super(FeedbackForm, self).__init__(data, files, *args, **kwargs)
There are some projects ongoing like BlobBuilder.js, however they are not guaranteed to work.