Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
File upload 
for the 21st century 
@jiripudil 
#posobota
Upload, anyone?
RFC 1867 
Form-based File Upload in HTML 
published 1995
RFC 1867 
<form enctype="multipart/form-data" 
method="post"> 
<input type="file">
Uploading in Nette 
$form->addUpload('file', 'File');
Uploading in Nette 
$form->addUpload('file', 'File') 
->addCondition($form::FILLED) 
->addRule($form::MAX_FILE_SIZE, 
NULL...
Uploading in Nette 
public function process($form, $values) { 
/** @var FileUpload $file */ 
$file = $values->file; 
}
Uploading multiple files 
$form->addUpload('file1', 'File 1'); 
$form->addUpload('file2', 'File 2'); 
$form->addUpload('fi...
Uploading multiple files
Uploading multiple files 
for ($i = 1; $i <= 100; $i++) { 
$form->addUpload("file$i", "File $i"); 
}
Uploading multiple files
Uploading multiple files
Uploading multiple files 
$form->addUpload('files', 'Files', TRUE); 
// or (nette/forms@master) 
$form->addMultiUpload('fi...
Uploading multiple files 
<input type="file" multiple>
Uploading multiple files 
public function process($form, $values) { 
/** @var FileUpload[] $files */ 
$files = $values->fi...
Asynchronous upload 
var data = new FormData(form); 
var xhr = new XMLHttpRequest; 
xhr.open('POST', form.action); 
xhr.on...
Progress tracking 
xhr.upload.onprogress = function (e) { 
if (e.lengthComputable) { 
var percentage = e.loaded / e.total;...
Drag'n'drop 
$('#dropzone').on('dragenter dragover', fn (e) 
{ 
if (%containsFiles%) { 
e.preventDefault(); 
} 
});
Drag'n'drop 
%containsFiles%: 
// FF, IE - types is 'DOMStringList' 
e.dataTransfer.types.contains('Files'); 
// WebKit - ...
Drag'n'drop 
$('#dropzone').on('drop', function (e) { 
e.preventDefault(); 
var data = new FormData(); 
var files = e.data...
What happens on the server side
What happens on the server side
What happens on the server side
Upload Module
What upload module does
Installation 
$ git clone -b 2.2 
https://github.com/vkholodkov/nginx-upload-module
Installation 
$ ./configure 
--add-module=/path/to/upload/module
Configuration 
client_max_body_size 32m; 
location /upload { 
upload_pass @upload; 
# ... 
} 
location @upload { 
rewrite ...
Configuration 
upload_store /tmp/upload 1; 
upload_store_access user:r group:r; 
upload_cleanup 400 404 499 500-505; 
uplo...
Configuration 
upload_set_form_field 
$upload_field_name[name] "$upload_file_name"; 
-"-[path] "$upload_file_path"; 
-"-[t...
Configuration 
upload_set_form_field 
$upload_field_name[$upload_file_number][name] 
"$upload_file_name"; 
upload_tame_arr...
Summary
Thanks! 
@jiripudil 
#posobota
File upload for the 21st century
File upload for the 21st century
File upload for the 21st century
File upload for the 21st century
File upload for the 21st century
File upload for the 21st century
File upload for the 21st century
File upload for the 21st century
File upload for the 21st century
File upload for the 21st century
File upload for the 21st century
File upload for the 21st century
File upload for the 21st century
Upcoming SlideShare
Loading in …5
×

File upload for the 21st century

855 views

Published on

A primer on how to implement effective and user-friendly asynchronous multiple file upload.

Published in: Software
  • Be the first to comment

File upload for the 21st century

  1. 1. File upload for the 21st century @jiripudil #posobota
  2. 2. Upload, anyone?
  3. 3. RFC 1867 Form-based File Upload in HTML published 1995
  4. 4. RFC 1867 <form enctype="multipart/form-data" method="post"> <input type="file">
  5. 5. Uploading in Nette $form->addUpload('file', 'File');
  6. 6. Uploading in Nette $form->addUpload('file', 'File') ->addCondition($form::FILLED) ->addRule($form::MAX_FILE_SIZE, NULL, 1024) ->addRule($form::IMAGE);
  7. 7. Uploading in Nette public function process($form, $values) { /** @var FileUpload $file */ $file = $values->file; }
  8. 8. Uploading multiple files $form->addUpload('file1', 'File 1'); $form->addUpload('file2', 'File 2'); $form->addUpload('file3', 'File 3'); // ... $form->addUpload('file100', 'File 100');
  9. 9. Uploading multiple files
  10. 10. Uploading multiple files for ($i = 1; $i <= 100; $i++) { $form->addUpload("file$i", "File $i"); }
  11. 11. Uploading multiple files
  12. 12. Uploading multiple files
  13. 13. Uploading multiple files $form->addUpload('files', 'Files', TRUE); // or (nette/forms@master) $form->addMultiUpload('files', 'Files');
  14. 14. Uploading multiple files <input type="file" multiple>
  15. 15. Uploading multiple files public function process($form, $values) { /** @var FileUpload[] $files */ $files = $values->files; }
  16. 16. Asynchronous upload var data = new FormData(form); var xhr = new XMLHttpRequest; xhr.open('POST', form.action); xhr.onreadystatechange = function (e) { if (xhr.readyState === 4) { // DONE if (xhr.status === 200) {} else {} } };
  17. 17. Progress tracking xhr.upload.onprogress = function (e) { if (e.lengthComputable) { var percentage = e.loaded / e.total; // display somewhere } }; xhr.send(data);
  18. 18. Drag'n'drop $('#dropzone').on('dragenter dragover', fn (e) { if (%containsFiles%) { e.preventDefault(); } });
  19. 19. Drag'n'drop %containsFiles%: // FF, IE - types is 'DOMStringList' e.dataTransfer.types.contains('Files'); // WebKit - types is Array e.dataTransfer.types.indexOf('Files') > -1;
  20. 20. Drag'n'drop $('#dropzone').on('drop', function (e) { e.preventDefault(); var data = new FormData(); var files = e.dataTransfer.files; for (var i = 0; i < files.length; i++) { data.append(files[i].name, files[i]); } });
  21. 21. What happens on the server side
  22. 22. What happens on the server side
  23. 23. What happens on the server side
  24. 24. Upload Module
  25. 25. What upload module does
  26. 26. Installation $ git clone -b 2.2 https://github.com/vkholodkov/nginx-upload-module
  27. 27. Installation $ ./configure --add-module=/path/to/upload/module
  28. 28. Configuration client_max_body_size 32m; location /upload { upload_pass @upload; # ... } location @upload { rewrite ^ index.php last; }
  29. 29. Configuration upload_store /tmp/upload 1; upload_store_access user:r group:r; upload_cleanup 400 404 499 500-505; upload_max_file_size 8m; upload_limit_rate 512k;
  30. 30. Configuration upload_set_form_field $upload_field_name[name] "$upload_file_name"; -"-[path] "$upload_file_path"; -"-[type] "$upload_content_type"; upload_aggregate_form_field -"-[size] "$upload_file_size"; -"-[md5] "$upload_file_md5"; upload_pass_form_field "submit";
  31. 31. Configuration upload_set_form_field $upload_field_name[$upload_file_number][name] "$upload_file_name"; upload_tame_arrays on;
  32. 32. Summary
  33. 33. Thanks! @jiripudil #posobota

×