Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/mailru/FileAPI
FileAPI — a set of javascript tools for working with files. Multiupload, drag'n'drop and chunked file upload. Images: crop, resize and auto orientation by EXIF.
https://github.com/mailru/FileAPI
Last synced: about 1 month ago
JSON representation
FileAPI — a set of javascript tools for working with files. Multiupload, drag'n'drop and chunked file upload. Images: crop, resize and auto orientation by EXIF.
- Host: GitHub
- URL: https://github.com/mailru/FileAPI
- Owner: mailru
- License: other
- Created: 2012-01-17T06:47:39.000Z (almost 13 years ago)
- Default Branch: master
- Last Pushed: 2020-09-24T08:35:44.000Z (about 4 years ago)
- Last Synced: 2024-10-18T00:00:16.841Z (about 2 months ago)
- Language: JavaScript
- Homepage: http://mailru.github.io/FileAPI/
- Size: 71.8 MB
- Stars: 3,574
- Watchers: 175
- Forks: 460
- Open Issues: 50
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-javascript - FileAPI - FileAPI — a set of javascript tools for working with files. Multiupload, drag'n'drop and chunked file upload. Images: crop, resize and auto orientation by EXIF. - ★ 3298 (Form Widgets)
- awesome-star-libs - mailru / FileAPI - 一组用于处理文件的JavaScript工具。多重上传,拖放和分块文件上传。图片:通过EXIF裁剪,调整大小和自动定向。 (目录)
README
## FileAPI
A set of JavaScript tools for working with files.Download the files from the [dist](https://github.com/mailru/FileAPI/tree/master/dist) directory, and then:
```html
Choose files
window.FileAPI = { staticPath: '/js/FileAPI/dist/' };
var choose = document.getElementById('choose');
FileAPI.event.on(choose, 'change', function (evt){
var files = FileAPI.getFiles(evt); // Retrieve file listFileAPI.filterFiles(files, function (file, info/**Object*/){
if( /^image/.test(file.type) ){
return info.width >= 320 && info.height >= 240;
}
return false;
}, function (files/**Array*/, rejected/**Array*/){
if( files.length ){
// Make preview 100x100
FileAPI.each(files, function (file){
FileAPI.Image(file).preview(100).get(function (err, img){
images.appendChild(img);
});
});// Uploading Files
FileAPI.upload({
url: './ctrl.php',
files: { images: files },
progress: function (evt){ /* ... */ },
complete: function (err, xhr){ /* ... */ }
});
}
});
});
```---
### Setup options
Edit the file `crossdomain.xml` and place it to the root of the domain to which files will be uploaded.```html
window.FileAPI = {
debug: false // debug mode, see Console
, cors: false // if used CORS, set `true`
, media: false // if used WebCam, set `true`
, staticPath: '/js/FileAPI/dist/' // path to '*.swf'
, postNameConcat: function (name, idx){
// Default: object[foo]=1&object[bar][baz]=2
// .NET: https://github.com/mailru/FileAPI/issues/121#issuecomment-24590395
return name + (idx != null ? '['+ idx +']' : '');
}
};
window.FileAPI = { /* options */ };
require(['FileAPI'], function (FileAPI){
// ...
});
```---
### getFiles(input`:HTMLInputElement|Event|$.Event`)`:Array`
Retrieve file list from `input` element or `event` object, also support `jQuery`.* input — `HTMLInputElement`, `change` and `drop` event, `jQuery` collection or `jQuery.Event`
```js
var el = document.getElement('my-input');
FileAPI.event.on(el, 'change', function (evt/**Event*/){
// Retrieve file list
var files = FileAPI.getFiles(el);// or event
var files = FileAPI.getFiles(evt);
});
```---
### getInfo(file`:Object`, callback`:Function`)`:void`
Get info of file (see also: FileAPI.addInfoReader).* file — file object (https://developer.mozilla.org/en-US/docs/DOM/File)
* callback — function, called after collected info of file```js
// Get info of image file (FileAPI.exif.js included)
FileAPI.getInfo(file, function (err/**String*/, info/**Object*/){
if( !err ){
console.log(info); // { width: 800, height: 600, exif: {..} }
}
});// Get info of mp3 file (FileAPI.id3.js included)
FileAPI.getInfo(file, function (err/**String*/, info/**Object*/){
if( !err ){
console.log(info); // { title: "...", album: "...", artists: "...", ... }
}
});
```---
### filterFiles(files`:Array`, filter`:Function`, callback`:Function`)`:void`
Filtering the list of files, with additional information about files.
See also: FileAPI.getInfo and FileAPI.addInfoReader.* files — original list of files
* filter — function, takes two arguments: `file` — the file itself, `info` — additional information.
* callback — function: `list` — files that match the condition, `other` — all the rest.```js
// Get list of file
var files = FileAPI.getFiles(input);// Filter the List
FileAPI.filterFiles(files, function (file/**Object*/, info/**Object*/){
if( /^image/.test(file.type) && info ){
return info.width > 320 && info.height > 240;
} else {
return file.size < 20 * FileAPI.MB;
}
}, function (list/**Array*/, other/**Array*/){
if( list.length ){
// ..
}
});
```---
### getDropFiles(evt`:Event|$.Event`, callback`:Function`)`:void`
Get a list of files, including directories.* evt — `drop` event
* callback — function, takes one argument, a list of files```js
FileAPI.event.on(document, 'drop', function (evt/**Event*/){
evt.preventDefault();// Get a list of files
FileAPI.getDropFiles(evt, function (files/**Array*/){
// ...
});
});
```---
### upload(opts`:Object`)`:XmlHttpRequest`
Uploading files to the server (successively). Returns XHR-like object.
It is important to remember to correctly worked flash-transport server response body must not be empty,
for example, you can pass, just text "ok".* opts — options object, see [Upload options](#options)
```js
var el = document.getElementById('my-input');
FileAPI.event.on(el, 'change', function (evt/**Event*/){
var files = FileAPI.getFiles(evt);
var xhr = FileAPI.upload({
url: 'http://rubaxa.org/FileAPI/server/ctrl.php',
files: { file: files[0] },
complete: function (err, xhr){
if( !err ){
var result = xhr.responseText;
// ...
}
}
});
});
```---
### addInfoReader(mime`:RegExp`, handler`:Function`)`:void`
Adds a handler for the collection of information about a file.
See also: FileAPI.getInfo and FileAPI.filterFiles.* mime — pattern of mime-type
* handler — takes two arguments: `file` object and `complete` function callback```js
FileAPI.addInfoReader(/^image/, function (file/**File*/, callback/**Function*/){
// http://www.nihilogic.dk/labs/exif/exif.js
// http://www.nihilogic.dk/labs/binaryajax/binaryajax.js
FileAPI.readAsBinaryString(file, function (evt/**Object*/){
if( evt.type == 'load' ){
var binaryString = evt.result;
var oFile = new BinaryFile(binaryString, 0, file.size);
var exif = EXIF.readFromBinaryFile(oFile);
callback(false, { 'exif': exif || {} });
}
else if( evt.type == 'error' ){
callback('read_as_binary_string');
}
else if( evt.type == 'progress' ){
// ...
}
});
});
```---
### readAsDataURL(file`:Object`, callback`:Function`)`:void`
Reading the contents of the specified `File` as `dataURL`.* file — file object
* callback — function, receives a result```js
FileAPI.readAsDataURL(file, function (evt/**Object*/){
if( evt.type == 'load' ){
// Success
var dataURL = evt.result;
} else if( evt.type =='progress' ){
var pr = evt.loaded/evt.total * 100;
} else {
// Error
}
})
```---
### readAsBinaryString(file`:Object`, callback`:Function`)`:void`
Reading the contents of the specified `File` as `BinaryString`.* file — file object
* callback — function, receives a result```js
FileAPI.readAsBinaryString(file, function (evt/**Object*/){
if( evt.type == 'load' ){
// Success
var binaryString = evt.result;
} else if( evt.type =='progress' ){
var pr = evt.loaded/evt.total * 100;
} else {
// Error
}
})
```---
### readAsArrayBuffer(file`:Object`, callback`:Function`)`:void`
Reading the contents of the specified `File` as `ArrayBuffer`.* file — file object
* callback — function, receives a result```js
FileAPI.readAsArrayBuffer(file, function (evt/**Object*/){
if( evt.type == 'load' ){
// Success
var arrayBuffer = evt.result;
} else if( evt.type =='progress' ){
var pr = evt.loaded/evt.total * 100;
} else {
// Error
}
})
```---
### readAsText(file`:Object`, callback`:Function`)`:void`
Reading the contents of the specified `File` as `text`.* file — file object
* callback — function, receives a result```js
FileAPI.readAsText(file, function (evt/**Object*/){
if( evt.type == 'load' ){
// Success
var text = evt.result;
} else if( evt.type =='progress' ){
var pr = evt.loaded/evt.total * 100;
} else {
// Error
}
})
```---
### readAsText(file`:Object`, encoding`:String`, callback`:Function`)`:void`
Reading the contents of the specified `File` as `text`.* encoding — a string indicating the encoding to use for the returned data. By default, UTF-8.
```js
FileAPI.readAsText(file, "utf-8", function (evt/**Object*/){
if( evt.type == 'load' ){
// Success
var text = evt.result;
} else if( evt.type =='progress' ){
var pr = evt.loaded/evt.total * 100;
} else {
// Error
}
})
```---
### url`:String`
A string containing the URL to which the request is sent.---
### data`:Object`
Additional post data to be sent along with the file uploads.```js
var xhr = FileAPI.upload({
url: '...',
data: { 'session-id': 123 },
files: { ... },
});
```---
### uploadMethod`:String`
Request method, HTML5 only.```js
var xhr = FileAPI.upload({
url: '...',
uploadMethod: 'PUT',
files: { .. },
});
```---
### uploadCredentials`:Boolean`
Pass credentials to upload request, HTML5 only.```js
var xhr = FileAPI.upload({
url: '...',
uploadCredentials: false,
files: { .. },
});
```---
### headers`:Object`
Additional request headers, HTML5 only.```js
var xhr = FileAPI.upload({
url: '...',
headers: { 'x-upload': 'fileapi' },
files: { .. },
});
```---
### cache`:Boolean`
Setting to true removes the default timestamp URL parameter.---
### files`:Object`
Key-value object, `key` — post name, `value` — File or FileAPI.Image object.```js
var xhr = FileAPI.upload({
url: '...',
files: {
audio: files
}
});
```---
### chunkSize`:Number`
Chunk size in bytes, HTML5 only.```js
var xhr = FileAPI.upload({
url: '...',
files: { images: fileList },
chunkSize: 0.5 * FileAPI.MB
});
```---
### chunkUploadRetry`:Number`
Number of retries during upload chunks, HTML5 only.```js
var xhr = FileAPI.upload({
url: '...',
files: { images: fileList },
chunkSize: 0.5 * FileAPI.MB,
chunkUploadRetry: 3
});
```--
### imageTransform`:Object`
Rules of changes the original image on the client.```js
var xhr = FileAPI.upload({
url: '...',
files: { image: imageFiles },
// Changes the original image
imageTransform: {
// resize by max side
maxWidth: 800,
maxHeight: 600,
// Add watermark
overlay: [{ x: 10, y: 10, src: '/i/watemark.png', rel: FileAPI.Image.RIGHT_BOTTOM }]
}
});
```--
### imageTransform`:Object`
Rules of image transformation on the client, for more images.```js
var xhr = FileAPI.upload({
url: '...',
files: { image: imageFiles },
imageTransform: {
// resize by max side
'huge': { maxWidth: 800, maxHeight: 600 },
// crop & resize
'medium': { width: 320, height: 240, preview: true },
// crop & resize + watemark
'small': {
width: 100, height: 100,
// Add watermark
overlay: [{ x: 5, y: 5, src: '/i/watemark.png', rel: FileAPI.Image.RIGHT_BOTTOM }]
}
}
});
```--
### imageTransform`:Object`
Convert all images to jpeg or png.```js
var xhr = FileAPI.upload({
url: '...',
files: { image: imageFiles },
imageTransform: {
type: 'image/jpeg',
quality: 0.86 // jpeg quality
}
});
```
### imageOriginal`:Boolean`
Sent to the server the original image or not, if defined imageTransform option.--
### imageAutoOrientation`:Boolean`
Auto-rotate images on the basis of EXIF.--
### prepare`:Function`
Prepare options upload for a particular file.```js
var xhr = FileAPI.upload({
url: '...',
files: { .. }
prepare: function (file/**Object*/, options/**Object*/){
options.data.secret = utils.getSecretKey(file.name);
}
});
```--
### upload`:Function`
Start uploading.```js
var xhr = FileAPI.upload({
url: '...',
files: { .. }
upload: function (xhr/**Object*/, options/**Object*/){
// ...
}
});
```--
### fileupload`:Function`
Start file uploading.```js
var xhr = FileAPI.upload({
url: '...',
files: { .. }
fileupload: function (file/**Object*/, xhr/**Object*/, options/**Object*/){
// ...
}
});
```--
### progress`:Function`
Callback for upload progress events.```js
var xhr = FileAPI.upload({
url: '...',
files: { .. }
progress: function (evt/**Object*/, file/**Object*/, xhr/**Object*/, options/**Object*/){
var pr = evt.loaded/evt.total * 100;
}
});
```--
### fileprogress`:Function`
Callback for upload file progress events.```js
var xhr = FileAPI.upload({
url: '...',
files: { .. }
fileprogress: function (evt/**Object*/, file/**Object*/, xhr/**Object*/, options/**Object*/){
var pr = evt.loaded/evt.total * 100;
}
});
```--
### complete`:Function`
Callback for end upload requests.```js
var xhr = FileAPI.upload({
url: '...',
files: { .. }
complete: function (err/**String*/, xhr/**Object*/, file/**Object/, options/**Object*/){
if( !err ){
// All files successfully uploaded.
}
}
});
```--
### filecomplete`:Function`
Callback for end upload requests.```js
var xhr = FileAPI.upload({
url: '...',
files: { .. }
filecomplete: function (err/**String*/, xhr/**Object*/, file/**Object/, options/**Object*/){
if( !err ){
// File successfully uploaded
var result = xhr.responseText;
}
}
});
```---
### name
The name of the file referenced by the File object.
### type
The type (MIME type) of the file referenced by the File object.
### size
The size (in bytes) of the file referenced by the File object.---
### on(el`:HTMLElement`, events`:String`, handler`:Function`)`:void`
Attach an event handler function.* el — DOM element
* events — one or more space-separated event types.
* handler — A function to execute when the event is triggered.---
### off(el`:HTMLElement`, events`:String`, handler`:Function`)`:void`
Remove an event handler.* el — DOM element
* events — one or more space-separated event types.
* handler — a handler function previously attached for the event(s).---
### one(el`:HTMLElement`, events`:String`, handler`:Function`)`:void`
Attach an event handler function. The handler is executed at most once.* el — DOM element
* events — one or more space-separated event types.
* handler — a function to execute when the event is triggered.---
### dnd(el`:HTMLElement`, hover`:Function`, handler`:Function`)`:void`
Attach an drag and drop event handler function.* el — drop zone
* hover — `dragenter` and `dragleave` listener
* handler — `drop` event handler.```js
var el = document.getElementById('dropzone');
FileAPI.event.dnd(el, function (over){
el.style.backgroundColor = over ? '#f60': '';
}, function (files){
if( files.length ){
// Upload their.
}
});// or jQuery
$('#dropzone').dnd(hoverFn, dropFn);
```---
### dnd.off(el`:HTMLElement`, hover`:Function`, handler`:Function`)`:void`
Remove an drag and drop event handler function.* el — drop zone
* hover — `dragenter` and `dragleave` listener
* handler — `drop` event handler.```js
// Native
FileAPI.event.dnd.off(el, hoverFn, dropFn);// jQuery
$('#dropzone').dndoff(hoverFn, dropFn);
```--
## FileAPI.Image
Class for working with images### constructor(file`:Object`)`:void`
The constructor takes a single argument, the `File` object.* file — the `File` object
```js
FileAPI.Image(imageFile).get(function (err/**String*/, img/**HTMLElement*/){
if( !err ){
document.body.appendChild( img );
}
});
```---
### crop(width`:Number`, height`:Number`)`:FileAPI.Image`
Crop image by width and height.* width — new image width
* height — new image height```js
FileAPI.Image(imageFile)
.crop(640, 480)
.get(function (err/**String*/, img/**HTMLElement*/){})
;
```### crop(x`:Number`, y`:Number`, width`:Number`, height`:Number`)`:FileAPI.Image`
Crop image by x, y, width and height.* x — offset from the top corner
* y — offset from the left corner```js
FileAPI.Image(imageFile)
.crop(100, 50, 320, 240)
.get(function (err/**String*/, img/**HTMLElement*/){})
;
```---
### resize(width`:Number`, height`:Number`[, strategy`:String`])`:FileAPI.Image`
Resize image.* width — new image width
* height — new image height
* strategy — enum: `min`, `max`, `preview`, `width`, `height`. By default `undefined`.```js
FileAPI.Image(imageFile)
.resize(320, 240)
.get(function (err/**String*/, img/**HTMLElement*/){})
;// Resize image on by max side.
FileAPI.Image(imageFile)
.resize(320, 240, 'max')
.get(function (err/**String*/, img/**HTMLElement*/){})
;// Resize image on by fixed height.
FileAPI.Image(imageFile)
.resize(240, 'height')
.get(function (err/**String*/, img/**HTMLElement*/){})
;
```---
### preview(width`:Number`[, height`:Number`])`:FileAPI.Image`
Crop and resize image.* width — new image width
* height — new image height```js
FileAPI.Image(imageFile)
.preview(100, 100)
.get(function (err/**String*/, img/**HTMLElement*/){})
;
```---
### rotate(deg`:Number`)`:FileAPI.Image`
Rotate image.* deg — rotation angle in degrees
```js
FileAPI.Image(imageFile)
.rotate(90)
.get(function (err/**String*/, img/**HTMLElement*/){})
;
```---
### filter(callback`:Function`)`:FileAPI.Image`
Apply filter function. Only `HTML5`.* callback — takes two arguments, `canvas` element and `done` method.
```js
FileAPI.Image(imageFile)
.filter(function (canvas/**HTMLCanvasElement*/, doneFn/**Function*/){
// bla-bla-lba
doneFn();
})
.get(function (err/**String*/, img/**HTMLElement*/){})
;
```---
### filter(name`:String`)`:FileAPI.Image`
Uses [CamanJS](http://camanjs.com/), include it before FileAPI library.* name — CamanJS filter name (custom or preset)
```js
Caman.Filter.register("my-funky-filter", function () {
// http://camanjs.com/guides/#Extending
});FileAPI.Image(imageFile)
.filter("my-funky-filter") // or .filter("vintage")
.get(function (err/**String*/, img/**HTMLElement*/){})
;
```---
### overlay(images`:Array`)`:FileAPI.Image`
Add overlay images, eg: watermark.* images — array of overlays
```js
FileAPI.Image(imageFile)
.overlay([
// Left corner.
{ x: 10, y: 10, w: 100, h: 10, src: '/i/watermark.png' },// Right bottom corner.
{ x: 10, y: 10, src: '/i/watermark.png', rel: FileAPI.Image.RIGHT_BOTTOM }
])
.get(function (err/**String*/, img/**HTMLElement*/){})
;
```---
### get(fn`:Function`)`:FileAPI.Image`
Get the final image.* fn — complete callback
---
## FileAPI.Camera
To work with a webcam, be sure to set `FileAPI.media: true`.
### publish(el`:HTMLElement`, options`:Object`, callback`:Function`)`:void`
Publication of the camera.* el — target
* options — { `width: 100%`, `height: 100%`, `start: true` }
* callback — the first parameter is a possible error, the second instance of FileAPI.Camera```js
var el = document.getElementById('cam');
FileAPI.Camera.publish(el, { width: 320, height: 240 }, function (err, cam/**FileAPI.Camera*/){
if( !err ){
// The webcam is ready, you can use it.
}
});
```---
### start(callback`:Function`)`:void`
Turn on the camera.* callback — will be called when the camera ready
```js
var el = document.getElementById('cam');
FileAPI.Camera.publish(el, { start: false }, function (err, cam/**FileAPI.Camera*/){
if( !err ){
// Turn on
cam.start(function (err){
if( !err ){
// The camera is ready for use.
}
});
}
});
```---
### stop()`:void`
Turn off the camera.---
### shot()`:FileAPI.Image`
Take a picture with the camera.```js
var el = document.getElementById('cam');
FileAPI.Camera.publish(el, function (err, cam/**FileAPI.Camera*/){
if( !err ){
var shot = cam.shot(); // take a picture// create thumbnail 100x100
shot.preview(100).get(function (err, img){
previews.appendChild(img);
});// and/or
FileAPI.upload({
url: '...',
files: { cam: shot
});
}
});
```---
### FileAPI.KB`:Number`
1024 bytes
### FileAPI.MB`:Number`
1048576 bytes
### FileAPI.GB`:Number`
1073741824 bytes
### FileAPI.TB`:Number`
1.0995116e+12 bytes---
### FileAPI.each(obj`:Object|Array`, callback`:Function`[, thisObject`:Mixed`])`:void`
Iterate over an object or array, executing a function for each matched element.* obj — array or object
* callback — a function to execute for each element.
* thisObject — object to use as `this` when executing `callback`.--
### FileAPI.extend(dst`:Object`, src`:Object`)`:Object`
Merge the contents of two objects together into the first object.* dst — an object that will receive the new properties
* src — an object containing additional properties to merge in.--
### FileAPI.filter(array`:Array`, callback`:Function`[, thisObject`:Mixed`)`:Object`
Creates a new array with all elements that pass the test implemented by the provided function.* array — original Array
* callback — Function to test each element of the array.
* thisObject — object to use as `this` when executing `callback`.---
- Multiupload: all browsers that support HTML5 or Flash
- Drag'n'Drop upload: files (HTML5) & directories (Chrome 21+)
- Chunked file upload (HTML5)
- Upload one file: all browsers
-
Working with Images: IE6+, FF 3.6+, Chrome 10+, Opera 11.1+, Safari 6+
- crop, resize, preview & rotate (HTML5 or Flash)
- auto orientation by exif (HTML5, if include FileAPI.exif.js or Flash)
### FileAPI.support.html5`:Boolean`
HTML5 browser support
### FileAPI.support.cors`:Boolean`
This cross-origin resource sharing is used to enable cross-site HTTP requests.
### FileAPI.support.dnd`:Boolean`
Drag'n'drop events support.
### FileAPI.support.flash`:Boolean`
Availability Flash plugin.
### FileAPI.support.canvas`:Boolean`
Canvas support.
### FileAPI.support.dataURI`:Boolean`
Support dataURI as src for image.
### FileAPI.support.chunked`:Boolean`
Support chunked upload.
---
## Flash
Flash is very "buggy" thing :]
The server response can not be empty.
Therefore, in the event of a successful uploading `http status` should be only `200 OK`.
### Settings
Flash settings.
It is advisable to place flash on the same server where the files will be uploaded.
```html
var FileAPI = {
// @default: "./dist/"
staticPath: '/js/',
// @default: FileAPI.staticPath + "FileAPI.flash.swf"
flashUrl: '/statics/FileAPI.flash.swf',
// @default: FileAPI.staticPath + "FileAPI.flash.image.swf"
flashImageUrl: '/statics/FileAPI.flash.image.swf'
};
```
---
### crossdomain.xml
Necessarily make this file on the server.
Do not forget to replace `youdomain.com` on the name of your domain.
```xml
```
---
### request
The following sample HTTP POST request is sent from Flash Player to a server-side script if no parameters are specified:
```xml
POST /server/ctrl.php HTTP/1.1
Accept: text/*
Content-Type: multipart/form-data;
boundary=----------Ij5ae0ae0KM7GI3KM7
User-Agent: Shockwave Flash
Host: www.youdomain.com
Content-Length: 421
Connection: Keep-Alive
Cache-Control: no-cache
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="Filename"
MyFile.jpg
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="Filedata"; filename="MyFile.jpg"
Content-Type: application/octet-stream
[[..FILE_DATA_HERE..]]
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7
Content-Disposition: form-data; name="Upload"
Submit Query
------------Ij5GI3GI3ei4GI3ei4KM7GI3KM7KM7--
```
---
### Security
By default `FileAPI.flash.swf` allows access from any domain via `Security.allowDomain("*")`.
This can lead to same origin bypass vulnerability if swf is loaded from the same domain as your critical data.
To prevent this, allow only your domains [here](https://github.com/mailru/FileAPI/blob/master/flash/core/src/ru/mail/communication/JSCallbackPresenter.as#L25) and rebuild flash.
---
```php
(function (ctx, jsonp){
'use strict';
var status = {{httpStatus}}, statusText = "{{httpStatusText}}", response = "{{responseBody}}";
try {
ctx[jsonp](status, statusText, response);
} catch (e){
var data = "{\"id\":\""+jsonp+"\",\"status\":"+status+",\"statusText\":\""+statusText+"\",\"response\":\""+response.replace(/\"/g, '\\\\\"')+"\"}";
try {
ctx.postMessage(data, document.referrer);
} catch (e){}
}
})(window.parent, '{{request_param_callback}}');
FileAPI::OK
, 'statusText' => 'OK'
, 'body' => array('count' => sizeof($files))
), $jsonp);
exit;
}
?>
```
---
```php
```
---
### Chunked file upload
Client and server communicate to each other using the following HTTP headers and status codes.
Client explicitly sets the following headers:
- Content-Range: bytes <start-offset>-<end-offset>/<total>
- Content-Disposition: attachment; filename=<file-name>
Any other headers are set by a target browser and are not used by client. Library does not provide any facilities to track a file uniqueness across requests, it's left on developer's consideration.
Response codes:
- 200 - last chunk is uploaded
- 201 - chunk is successfully saved
- 416 - range is not acceptable error, recoverable
- 500 - server error, recoverable
For recoverable errors server tries to resend chunk `chunkUploadRetry` times then fails.
All the other codes - fatal error, user's involvement is recommended.
---
### Base
Simple input[type="file"]
```html
```
---
```html
.upload-btn {
width: 130px;
height: 25px;
overflow: hidden;
position: relative;
border: 3px solid #06c;
border-radius: 5px;
background: #0cf;
}
.upload-btn:hover {
background: #09f;
}
.upload-btn__txt {
z-index: 1;
position: relative;
color: #fff;
font-size: 18px;
font-family: "Helvetica Neue";
line-height: 24px;
text-align: center;
text-shadow: 0 1px 1px #000;
}
.upload-btn input {
top: -10px;
right: -40px;
z-index: 2;
position: absolute;
cursor: pointer;
opacity: 0;
filter: alpha(opacity=0);
font-size: 50px;
}
```
---
```html
.upload-link {
color: #36c;
display: inline-block;
*zoom: 1;
*display: inline;
overflow: hidden;
position: relative;
padding-bottom: 2px;
text-decoration: none;
}
.upload-link__txt {
z-index: 1;
position: relative;
border-bottom: 1px dotted #36c;
}
.upload-link:hover .upload-link__txt {
color: #f00;
border-bottom-color: #f00;
}
.upload-link input {
top: -10px;
right: -40px;
z-index: 2;
position: absolute;
cursor: pointer;
opacity: 0;
filter: alpha(opacity=0);
font-size: 50px;
}
Upload photo
```
---
## Installation, testing, assembling
`npm install fileapi`
`cd fileapi`
`npm install`
`grunt`
---
### 2.0.20
- #369: * IEMobile
### 2.0.19
- #367: * [flash] allow gif and bmp to resize
### 2.0.18
- #364: * Camera#stop
- #363: * support `Blob` in `FileAPI.getInfo`
- #361: + upload zero-files
### 2.0.16-2.0.17
- #353: debug mode vs. IE
- #352: correct filename via flash-uploading
### 2.0.12-2.0.15 (!)
- #346, #342, #344: fixes for XSS into Flash-transport
### 2.0.11
- #322, #308: dnd & safari + $.fn.dnd (store all dropped items)
- #319: NodeJS tesing
- #317, #313: fixed "malformed entry.name (OSX Unicode NFD)"
- #311: fixed "Arithmetic result exceeded 32 bits"
### 2.0.10
- #289: * WebCam & html5 == false
- #199, #265: flash fix 2015 error with BitmapData
- #177: IE9, IE11 flash.camera remembered settigns
- #254: check 'onLoadFnName' before call
- #272: fixed `entry.createReader().readEntries`
### 2.0.9
- #253: fixed `proxyXHR.loaded`
- #250: + check `disabled`-attr
### 2.0.8
- Two new resize strategies `width` and `height`
### 2.0.7
- #214: iframe transport under IE8
- Fixed iframe-transport (remove `disabled`-attr for input)
### 2.0.6
- #240: Fixed `FileAPI.event.dnd.off`
### 2.0.5
- + #228: check callbacks with regexp
- * Updated devDepending
- + #207: support EXIF.Orientation == 4, 5 & 7
### 2.0.4
- + #176: Add params to the beginning of form
- + #190: Add 204 as a successful response
- + #192: many bugfixes; + `retry` & `multipass` options; + QUnit-tests for BigSizeImage
### 2.0.3
- + QUnit-tests for iframe-transport
- + `postMessage` for iframe-transport
- + `jsonp: "callback"` option
- * resize: `imageTransform.type` rename to `imageTransform.strategy` (!!!)
- + https://github.com/mailru/FileAPI/pull/165 (#140: fix)
### 2.0.2
- + test: upload headers
- + test: upload + camanjs
- + test: upload + autoOrientation
- FileAPI.class.php: + HTTP header Content-Type: application/json
- #143: + `FileAPI.flashWebcamUrl` option
- * merge v1.2.7
- + `FileAPI.formData: true` option
### 2.0.1
- + support 'filter' prop in imageTransform
### 2.0.0
- + FileAPI.Camera (HTML5 and Flash fallback)
- + jquery.fileapi.js, see demo
- + npm support
- + grunt support
- + requirejs support
- + [#80](https://https://github.com/mailru/FileAPI/issues/80): FileAPI.Image.fn.overlay
- `imageTransform` — now supports: `crop`, `type`, `quality` and `overlay` properties.
- Improved the documentation
- +iOS fix (https://github.com/blueimp/JavaScript-Load-Image)
- [#121](https://github.com/mailru/FileAPI/issues/121): + FileAPI.`postNameConcat:Function(name, idx)`
- [#116](https://github.com/mailru/FileAPI/issues/116): + `cache:false` option for FileAPI.upload
### 1.2.6
- [#91](https://github.com/mailru/FileAPI/issues/91): replace `new Image` to `FileAPI.newImage`
- + FileAPI.withCredentials: true
- [#90](https://github.com/mailru/FileAPI/issues/90): Fixed `progress` event
- [#105](https://github.com/mailru/FileAPI/issues/105): Fixed `image/jpg` -> `image/jpeg`
- [#108](https://github.com/mailru/FileAPI/issues/108): Check width/height before resize by type(min/max)
### 1.2.5
- [#86](https://github.com/mailru/FileAPI/issues/86): Smarter upload recovery
- [#87](https://github.com/mailru/FileAPI/issues/87): Fixed upload files into browsers that do not support FormData
- Fixed support "accept" attribute for Flash.
- Fixed detection of HTML5 support for FireFox 3.6
- + FileAPI.html5 option, default "true"
### 1.2.4
- Fixed auto orientation image by EXIF (Flash)
- Fixed image dimensions after rotate (Flash)
- [#82](https://github.com/mailru/FileAPI/issues/82): "undefined" data-fields cause exceptions
- [#83](https://github.com/mailru/FileAPI/issues/83): Allow requests without files
- [#84](https://github.com/mailru/FileAPI/pull/84): Fixed connection abort when waiting for connection recovery
### 1.2.3
- [#77](https://github.com/mailru/FileAPI/pull/77): Fixed flash.abort(), [#75](https://github.com/mailru/FileAPI/issues/75)
- - `FileAPI.addMime`
- + `FileAPI.accept` — fallback for flash.
### 1.2.2
- [#67](https://github.com/mailru/FileAPI/pull/67): Added correct httpStatus for upload fail, [#62](https://github.com/mailru/FileAPI/pull/68)
- [#68](https://github.com/mailru/FileAPI/pull/68) Added "Content-Type" for chunked upload, [#65](https://github.com/mailru/FileAPI/pull/65)
- [#69](https://github.com/mailru/FileAPI/issues/69): Fixed network down recovery
- Fixed progress event, [#66](https://github.com/mailru/FileAPI/issues/66)
- Increase flash stage size, [#73](https://github.com/mailru/FileAPI/pull/73)
- - array index from POST-param "name", [#72](https://github.com/mailru/FileAPI/issues/72)
- - dependency on FileAPI.Image for FileAPI.Flash
### 1.2.1
- [#64](https://github.com/mailru/FileAPI/issues/64): Bufixed for [#63](https://github.com/mailru/FileAPI/issues/63)
### 1.2.0
- [#57](https://github.com/mailru/FileAPI/issues/57): Chunked file upload
### 1.1.0
- [#54](https://github.com/mailru/FileAPI/issues/54): added `FileAPI.flashUrl` and `FileAPI.flashImageUrl`
### 1.0.1
- [#51](https://github.com/mailru/FileAPI/issues/51): remove circular references from `file-objects` (Flash transport)
- added `changelog`
### 1.0.0
- first release