UNPKG

4.65 kBMarkdownView Raw
1# uppie
2[![](https://img.shields.io/npm/v/uppie.svg?style=flat)](https://www.npmjs.org/package/uppie) [![](https://img.shields.io/npm/dm/uppie.svg)](https://www.npmjs.org/package/uppie) [![](https://img.shields.io/bundlephobia/minzip/uppie.svg)](https://bundlephobia.com/package/uppie)
3
4> Cross-browser file and directory and upload library
5
6`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.
7
8## Usage
9```bash
10npm install uppie
11```
12```js
13import Uppie from 'uppie';
14
15const uppie = new Uppie();
16uppie(document.querySelector('#file'), async (event, formData, files) => {
17 await fetch('/upload', {method: 'POST', body: formData});
18});
19```
20
21## Browser support
22
23|| files via input[file] | files via DnD | directories via input[file] | directories via DnD |
24|---------|---------------------- |---------------|----------------------|--------------|
25| Firefox | yes | yes | yes (50+) | yes (50+) |
26| Chrome | yes | yes | yes (29+) | yes (29+) |
27| Edge | yes | yes | yes (13+) | yes (14+) |
28| Safari | yes | yes | yes (11.1+) | yes (11.1+) |
29
30## Notes
31
32- Empty directories are excluded from the results by all browsers as dictated by the spec.
33- Firefox and Safari exclude files and directories starting with a `.`.
34
35## API
36### uppie(node, [opts], callback)
37- `node` *Node* or *NodeList*: One or more DOM nodes. If a `<input type="file">` is given, uppie will monitor it for `change` events. Any other element type will be enabled as a dropzone and watched for `drop` events. If you want to use both on the same element, use a hidden `<input>` and forward the click event.
38- `opts` *Object*: A options object which can contain:
39 - `name`: The `name` attribute for creating the FormData entries. Default: `"files[]"`.
40- `callback` *Function*: callback which is called every time the selected files change or when files are dropped in the dropzone.
41
42The callback receives
43
44- `event` *Event*: the original event. Useful for calling `event.stopPropagation()`.
45- `formData` *FormData*: FormData object to be used for XHR2 uploading.
46- `files` *Array*: Array of paths for preview purposes.
47
48#### FormData format
49
50`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:
51
52```
53------Boundary
54Content-Disposition: form-data; name="files[]"; filename="docs/1.txt"
55Content-Type: text/plain
56
57[DATA]
58------Boundary
59Content-Disposition: form-data; name="files[]"; filename="docs/path/2.txt"
60Content-Type: text/plain
61
62[DATA]
63------Boundary
64Content-Disposition: form-data; name="files[]"; filename="docs/path/to/3.txt"
65Content-Type: text/plain
66```
67
68## Recommended `input` element attributes
69
70- `multiple`: allow multiple files to be selected.
71- `webkitdirectory`: enable directory uploads in Chrome and Firefox.
72- `allowdirs`: enable experimental directory upload API in Firefox and Edge.
73
74## PHP example
75
76Below 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.
77
78````js
79const uppie = new Uppie();
80uppie(document.documentElement, (event, formData, files) => {
81 files.forEach(path => {
82 formData.append("paths[]", path);
83 });
84
85 const xhr = new XMLHttpRequest();
86 xhr.open('POST', 'upload.php');
87 xhr.send(formData);
88});
89````
90And in `upload.php`:
91````php
92foreach ($_FILES['files']['name'] as $i => $name) {
93 if (strlen($_FILES['files']['name'][$i]) > 1) {
94 $fullpath = strip_tags($_POST['paths'][$i]);
95 $path = dirname($fullpath);
96
97 if (!is_dir('uploads/'.$path)){
98 mkdir('uploads/'.$path);
99 }
100 if (move_uploaded_file($_FILES['files']['tmp_name'][$i], 'uploads/'.$fullpath)) {
101 echo '<li>'.$name.'</li>';
102 }
103 }
104}
105````
106
107Note that PHP's [upload limits](http://php.net/manual/en/ini.core.php#ini.sect.file-uploads) might need to be raised depending on use case.
108
109© [silverwind](https://github.com/silverwind), distributed under BSD licence
110
\No newline at end of file