uppie v4.0.0
uppie
Cross-browser file and directory and upload library
uppie is a tiny JavaScript library which helps you with file and directory uploads in browsers. It supports all current and past implementations of multi-file and directory uploads and provides you with a FormData object you can submit directly to a server through either XMLHttpRequest or fetch. Both the <input type="file"> element and drag-and-drop are supported.
Usage
npm install uppieimport {uppie} from 'uppie';
uppie(document.querySelector('#file'), async (e, formData, files) => {
await fetch('/upload', {method: 'POST', body: formData});
});Browser support
| files via inputtype=file | files via DnD | directories via inputtype=file | directories via DnD | |
|---|---|---|---|---|
| Firefox | yes | yes | yes (50+) | yes (50+) |
| Chrome | yes | yes | yes (29+) | yes (29+) |
| Edge | yes | yes | yes (13+) | yes (14+) |
| Safari | yes | yes | yes (11.1+) | yes (11.1+) |
Notes
- Empty directories are excluded from the results by all browsers as dictated by the spec.
- Firefox and Safari exclude files and directories starting with a
..
API
uppie(node, opts, callback)
nodeNode or NodeList: One or more DOM nodes. If a<input type="file">is given, uppie will monitor it forchangeevents. Any other element type will be enabled as a dropzone and watched fordropevents. If you want to use both on the same element, use a hidden<input>and forward the click event.optsObject: A options object which can contain:name: Thenameattribute for creating the FormData entries. Default:"files[]".
callbackFunction: callback which is called every time the selected files change or when files are dropped in the dropzone.
The callback receives
eventEvent: the original event. Useful for callingevent.stopPropagation().formDataFormData: FormData object to be used for XHR2 uploading.filesArray: Array of paths for preview purposes.
FormData format
name defaults to "files[]", filename will be the full path to the file, with / used as path separator. Does not include a leading slash. Make sure to sanitize filename on the server before writing it to the disk to prevent exploits involving .. in the path. Example FormData:
------Boundary
Content-Disposition: form-data; name="files[]"; filename="docs/1.txt"
Content-Type: text/plain
[DATA]
------Boundary
Content-Disposition: form-data; name="files[]"; filename="docs/path/2.txt"
Content-Type: text/plain
[DATA]
------Boundary
Content-Disposition: form-data; name="files[]"; filename="docs/path/to/3.txt"
Content-Type: text/plainRecommended input element attributes
multiple: allow multiple files or directories to be selected.webkitdirectory: enable directory uploads.
PHP example
Below is example for PHP 7.0 and possibly earlier versions. PHP does not parse the path from the filename field, so it is necessary to submit the path through other means, like as separate FormData fields as done in the example.
import {uppie} from 'uppie';
const uppie = new Uppie();
uppie(document.documentElement, (event, formData, files) => {
files.forEach(path => {
formData.append("paths[]", path);
});
const xhr = new XMLHttpRequest();
xhr.open('POST', 'upload.php');
xhr.send(formData);
});And in upload.php:
foreach ($_FILES['files']['name'] as $i => $name) {
if (strlen($_FILES['files']['name'][$i]) > 1) {
$fullpath = strip_tags($_POST['paths'][$i]);
$path = dirname($fullpath);
if (!is_dir('uploads/'.$path)){
mkdir('uploads/'.$path);
}
if (move_uploaded_file($_FILES['files']['tmp_name'][$i], 'uploads/'.$fullpath)) {
echo '<li>'.$name.'</li>';
}
}
}Note that PHP's upload limits might need to be raised depending on use case.
© silverwind, distributed under BSD licence
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
5 years ago
6 years ago
6 years ago
6 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago