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.
Top Related Projects
File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.
The next open source file uploader for web browsers :dog:
Multiple file upload plugin with image previews, drag and drop, progress bars. S3 and Azure support, image scaling, form support, chunking, resume, pause, and tons of other features.
Dropzone is an easy to use drag'n'drop library. It supports image previews and shows nice progress bars.
A JavaScript library for providing multiple simultaneous, stable, fault-tolerant and resumable/restartable uploads via the HTML5 File API.
A JavaScript library providing multiple simultaneous, stable, fault-tolerant and resumable/restartable file uploads via the HTML5 File API.
Quick Overview
The mailru/FileAPI
project is a JavaScript library that provides a set of tools for working with files in the browser. It aims to provide a consistent and cross-browser compatible API for file manipulation, including file uploads, downloads, and drag-and-drop functionality.
Pros
- Cross-browser Compatibility: The library is designed to work across a wide range of modern browsers, providing a consistent API and functionality.
- Comprehensive File Handling: The library offers a range of features for working with files, including file uploads, downloads, and drag-and-drop.
- Asynchronous File Processing: The library supports asynchronous file processing, allowing for efficient and non-blocking file operations.
- Extensible and Customizable: The library is designed to be extensible, with the ability to add custom file handlers and modify the default behavior.
Cons
- Dependency on Polyfills: The library may require the use of polyfills to ensure full compatibility with older browsers.
- Limited Documentation: The project's documentation could be more comprehensive, making it more challenging for new users to get started.
- Potential Performance Issues: Depending on the size and number of files being processed, the library may have performance implications, especially on older or less powerful devices.
- Lack of Active Maintenance: The project appears to have limited active maintenance, with the last commit being over a year ago.
Code Examples
Here are a few examples of how to use the mailru/FileAPI
library:
Uploading a File
var file = document.getElementById('file-input').files[0];
FileAPI.upload({
url: '/upload',
files: { 'file': file },
data: { 'key': 'value' },
complete: function (err, xhr) {
if (err) {
console.error('Upload error:', err);
} else {
console.log('Upload successful:', xhr.responseText);
}
}
});
This code demonstrates how to upload a file using the FileAPI.upload()
method, specifying the upload URL, the file to be uploaded, and any additional data to be sent with the request.
Resizing an Image
var file = document.getElementById('file-input').files[0];
FileAPI.Image(file)
.resize(320, 240)
.get(function (err, img) {
if (err) {
console.error('Image processing error:', err);
} else {
// Do something with the resized image
console.log('Resized image:', img);
}
});
This code shows how to use the FileAPI.Image()
method to resize an image, specifying the desired dimensions and then retrieving the processed image.
Handling Drag and Drop
document.addEventListener('drop', function (event) {
event.preventDefault();
FileAPI.event(event)
.done(function (files) {
// Handle the dropped files
console.log('Dropped files:', files);
})
.fail(function (err) {
console.error('Drag and drop error:', err);
});
}, false);
This code demonstrates how to handle file drop events using the FileAPI.event()
method, which provides a consistent API for working with dropped files across different browsers.
Getting Started
To get started with the mailru/FileAPI
library, you can follow these steps:
- Include the library in your HTML file:
<script src="https://cdn.jsdelivr.net/npm/file-api@2.3.29/dist/FileAPI.min.js"></script>
- Initialize the library and start using its methods:
// Initialize the library
FileAPI.html5 = true;
FileAPI.forceLoad = true;
// Use the library's methods
FileAPI.upload({
// ...
});
- Refer to the library's documentation for more detailed information on the available methods and features.
Competitor Comparisons
File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.
Pros of jQuery-File-Upload
- More comprehensive documentation and examples
- Wider browser support, including older versions
- Extensive plugin system for added functionality
Cons of jQuery-File-Upload
- Larger file size and potential performance overhead due to jQuery dependency
- Less focus on modern JavaScript practices and ES6+ features
Code Comparison
FileAPI:
FileAPI.upload({
url: '/upload',
files: { file: fileInput },
progress: function (evt) {
var progress = evt.loaded / evt.total * 100;
},
complete: function (err, xhr) {
if (!err) {
console.log('Upload complete');
}
}
});
jQuery-File-Upload:
$('#fileupload').fileupload({
url: '/upload',
dataType: 'json',
done: function (e, data) {
$.each(data.result.files, function (index, file) {
$('<p/>').text(file.name).appendTo(document.body);
});
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .bar').css('width', progress + '%');
}
});
Both libraries offer file upload functionality, but FileAPI focuses on a more lightweight, vanilla JavaScript approach, while jQuery-File-Upload provides a feature-rich solution with jQuery integration. FileAPI may be preferable for projects prioritizing performance and modern JavaScript practices, while jQuery-File-Upload excels in projects requiring extensive customization and broad browser support.
The next open source file uploader for web browsers :dog:
Pros of Uppy
- More active development with frequent updates and releases
- Extensive plugin ecosystem for added functionality
- Modern, modular architecture with support for various UI frameworks
Cons of Uppy
- Larger file size and potentially higher resource usage
- Steeper learning curve due to more complex API and configuration options
Code Comparison
FileAPI:
FileAPI.upload({
url: '/upload',
files: { file: fileInput },
complete: function (err, xhr) {
if (!err) {
console.log('Upload complete');
}
}
});
Uppy:
const uppy = new Uppy()
.use(XHRUpload, { endpoint: '/upload' })
.on('complete', (result) => {
console.log('Upload complete', result.successful)
});
uppy.addFile({
name: 'file.jpg',
type: 'image/jpeg',
data: fileInput
});
uppy.upload();
Key Differences
- FileAPI offers a simpler API for basic upload tasks
- Uppy provides more granular control over the upload process
- Uppy's plugin system allows for easy integration of additional features
- FileAPI has a smaller footprint but fewer built-in capabilities
- Uppy offers better support for modern web development practices and frameworks
Both libraries serve the purpose of handling file uploads, but Uppy is more feature-rich and adaptable to complex use cases, while FileAPI is lighter and easier to implement for simpler scenarios.
Multiple file upload plugin with image previews, drag and drop, progress bars. S3 and Azure support, image scaling, form support, chunking, resume, pause, and tons of other features.
Pros of Fine-Uploader
- More comprehensive documentation and examples
- Wider browser support, including older versions
- Active community and regular updates
Cons of Fine-Uploader
- Larger file size and potentially more complex setup
- Less flexible for custom implementations
- Steeper learning curve for beginners
Code Comparison
FileAPI:
FileAPI.upload({
url: '/upload',
files: { file: fileInput },
complete: function (err, xhr) {
if (!err) {
console.log('Upload complete');
}
}
});
Fine-Uploader:
var uploader = new qq.FineUploader({
element: document.getElementById('uploader'),
request: {
endpoint: '/upload'
},
callbacks: {
onComplete: function(id, name, response) {
console.log('Upload complete');
}
}
});
Summary
Fine-Uploader offers a more feature-rich and well-documented solution with broader browser support, making it suitable for complex projects. However, it may be overkill for simpler implementations. FileAPI provides a lighter-weight alternative with more flexibility for custom solutions but may require more effort to implement advanced features. The choice between the two depends on project requirements, desired level of control, and development team expertise.
Dropzone is an easy to use drag'n'drop library. It supports image previews and shows nice progress bars.
Pros of Dropzone
- More active development and maintenance
- Extensive documentation and examples
- Easier to set up and use with a simpler API
Cons of Dropzone
- Larger file size and potentially heavier on resources
- Less flexible for advanced customization
Code Comparison
FileAPI:
FileAPI.upload({
url: '/upload',
files: { file: fileInput },
progress: function (evt) {},
complete: function (err, xhr) {}
});
Dropzone:
Dropzone.options.myDropzone = {
url: "/upload",
init: function() {
this.on("uploadprogress", function(file, progress) {});
this.on("complete", function(file) {});
}
};
Key Differences
- FileAPI offers more low-level control and flexibility
- Dropzone provides a more user-friendly interface out of the box
- FileAPI supports a wider range of browsers, including older versions
- Dropzone has better integration with modern web frameworks
Use Cases
- Choose FileAPI for projects requiring fine-grained control over file handling
- Opt for Dropzone when rapid development and ease of use are priorities
Community and Support
- Dropzone has a larger community and more third-party resources
- FileAPI has fewer contributors but offers more specialized functionality
A JavaScript library for providing multiple simultaneous, stable, fault-tolerant and resumable/restartable uploads via the HTML5 File API.
Pros of resumable.js
- Focuses specifically on chunked and resumable file uploads
- Supports parallel uploads for improved performance
- Provides a more streamlined API for handling large file uploads
Cons of resumable.js
- Less comprehensive file handling features compared to FileAPI
- Limited to modern browsers with File API support
- Smaller community and fewer updates in recent years
Code Comparison
FileAPI:
FileAPI.upload({
url: '/upload',
files: { file: fileInput },
progress: function (evt) {
console.log(evt.loaded / evt.total * 100 + '%');
}
});
resumable.js:
var r = new Resumable({
target: '/upload',
chunkSize: 1*1024*1024
});
r.addFile(file);
r.on('fileProgress', function(file){
console.log(file.progress() * 100 + '%');
});
r.upload();
Summary
FileAPI offers a more comprehensive set of file handling features, including image manipulation and cross-browser support. It's suitable for projects requiring extensive file operations beyond just uploading.
resumable.js, on the other hand, specializes in chunked and resumable file uploads, making it ideal for scenarios involving large file transfers or unreliable network connections. Its API is more focused and potentially easier to use for specific upload tasks.
The choice between the two depends on the project's specific requirements, with FileAPI being more versatile and resumable.js excelling in its niche of robust file uploads.
A JavaScript library providing multiple simultaneous, stable, fault-tolerant and resumable/restartable file uploads via the HTML5 File API.
Pros of flow.js
- More active development with recent updates and releases
- Better documentation and examples for easier implementation
- Supports chunked uploads for improved performance with large files
Cons of flow.js
- Limited file type handling compared to FileAPI
- Lacks some advanced features like image manipulation and EXIF data extraction
Code Comparison
FileAPI:
FileAPI.upload({
url: '/upload',
files: { file: fileInput },
progress: function (evt) {
console.log(evt.loaded / evt.total * 100 + '%');
}
});
flow.js:
var flow = new Flow({
target: '/upload',
chunkSize: 1024 * 1024
});
flow.addFile(file);
flow.on('progress', function () {
console.log(flow.progress() * 100 + '%');
});
Both libraries provide similar functionality for file uploads, but flow.js offers a more modern API with support for chunked uploads. FileAPI provides a simpler interface but with fewer advanced features. flow.js is generally more suitable for projects requiring efficient handling of large files, while FileAPI might be preferred for its broader file type support and image manipulation capabilities.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
FileAPI
A set of JavaScript tools for working with files.
Get started
Download the files from the dist directory, and then:
<div>
<!-- "js-fileapi-wrapper" -- required class -->
<div class="js-fileapi-wrapper upload-btn">
<div class="upload-btn__txt">Choose files</div>
<input id="choose" name="files" type="file" multiple />
</div>
<div id="images"><!-- previews --></div>
</div>
<script>window.FileAPI = { staticPath: '/js/FileAPI/dist/' };</script>
<script src="/js/FileAPI/dist/FileAPI.min.js"></script>
<script>
var choose = document.getElementById('choose');
FileAPI.event.on(choose, 'change', function (evt){
var files = FileAPI.getFiles(evt); // Retrieve file list
FileAPI.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){ /* ... */ }
});
}
});
});
</script>
Setup options
Edit the file crossdomain.xml
and place it to the root of the domain to which files will be uploaded.
<script>
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 +']' : '');
}
};
</script>
<script src="/js/FileAPI/dist/FileAPI.min.js"></script>
<!-- OR -->
<script>
window.FileAPI = { /* options */ };
require(['FileAPI'], function (FileAPI){
// ...
});
</script>
getFiles(input:HTMLInputElement|Event|$.Event
):Array
Retrieve file list from input
element or event
object, also support jQuery
.
- input â
HTMLInputElement
,change
anddrop
event,jQuery
collection orjQuery.Event
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
// 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.
// 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
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
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 andcomplete
function callback
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
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
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
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
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.
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
}
})
Upload options
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.
var xhr = FileAPI.upload({
url: '...',
data: { 'session-id': 123 },
files: { ... },
});
uploadMethod:String
Request method, HTML5 only.
var xhr = FileAPI.upload({
url: '...',
uploadMethod: 'PUT',
files: { .. },
});
uploadCredentials:Boolean
Pass credentials to upload request, HTML5 only.
var xhr = FileAPI.upload({
url: '...',
uploadCredentials: false,
files: { .. },
});
headers:Object
Additional request headers, HTML5 only.
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.
var xhr = FileAPI.upload({
url: '...',
files: {
audio: files
}
});
chunkSize:Number
Chunk size in bytes, HTML5 only.
var xhr = FileAPI.upload({
url: '...',
files: { images: fileList },
chunkSize: 0.5 * FileAPI.MB
});
chunkUploadRetry:Number
Number of retries during upload chunks, HTML5 only.
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.
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.
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.
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.
var xhr = FileAPI.upload({
url: '...',
files: { .. }
prepare: function (file/**Object*/, options/**Object*/){
options.data.secret = utils.getSecretKey(file.name);
}
});
--
upload:Function
Start uploading.
var xhr = FileAPI.upload({
url: '...',
files: { .. }
upload: function (xhr/**Object*/, options/**Object*/){
// ...
}
});
--
fileupload:Function
Start file uploading.
var xhr = FileAPI.upload({
url: '...',
files: { .. }
fileupload: function (file/**Object*/, xhr/**Object*/, options/**Object*/){
// ...
}
});
--
progress:Function
Callback for upload progress events.
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.
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.
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.
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;
}
}
});
File object
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.
FileAPI.event
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
anddragleave
listener - handler â
drop
event handler.
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
anddragleave
listener - handler â
drop
event handler.
// 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
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
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
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 defaultundefined
.
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
FileAPI.Image(imageFile)
.preview(100, 100)
.get(function (err/**String*/, img/**HTMLElement*/){
})
;
rotate(deg:Number
):FileAPI.Image
Rotate image.
- deg â rotation angle in degrees
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 anddone
method.
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, include it before FileAPI library.
- name â CamanJS filter name (custom or preset)
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
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
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
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.
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
});
}
});
Constants
FileAPI.KB:Number
1024 bytes
FileAPI.MB:Number
1048576 bytes
FileAPI.GB:Number
1073741824 bytes
FileAPI.TB:Number
1.0995116e+12 bytes
Utils
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 executingcallback
.
--
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 executingcallback
.
Support
- 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.
<script>
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'
};
</script>
<script src="/js/FileAPI.min.js"></script>
crossdomain.xml
Necessarily make this file on the server.
Do not forget to replace youdomain.com
on the name of your domain.
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="youdomain.com" secure="false"/>
<allow-access-from domain="*.youdomain.com" secure="false"/>
<allow-http-request-headers-from domain="*" headers="*" secure="false"/>
</cross-domain-policy>
request
The following sample HTTP POST request is sent from Flash Player to a server-side script if no parameters are specified:
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 and rebuild flash.
Server settings
IFrame/JSONP
<script>
(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}}');
</script>
<!-- or -->
<?php
include './FileAPI.class.php';
if( strtoupper($_SERVER['REQUEST_METHOD']) == 'POST' ){
// Retrieve File List
$files = FileAPI::getFiles();
// ... your logic
// JSONP callback name
$jsonp = isset($_REQUEST['callback']) ? trim($_REQUEST['callback']) : null;
// Server response: "HTTP/1.1 200 OK"
FileAPI::makeResponse(array(
'status' => FileAPI::OK
, 'statusText' => 'OK'
, 'body' => array('count' => sizeof($files))
), $jsonp);
exit;
}
?>
CORS
Enable CORS.
<?php
// Permitted types of request
header('Access-Control-Allow-Methods: POST, OPTIONS');
// Describe custom headers
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Range, Content-Disposition, Content-Type');
// A comma-separated list of domains
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
// Allow cookie
header('Access-Control-Allow-Credentials: true');
if( $_SERVER['REQUEST_METHOD'] == 'OPTIONS' ){
exit;
}
if( $_SERVER['REQUEST_METHOD'] == 'POST' ){
// ...
}
?>
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>
Response codes:
- 200 - last chunk is uploaded
- 201 - chunk is successfully saved
- 416 - range is not acceptable error, recoverable
- 500 - server error, recoverable
Buttons examples
Base
Simple input[type="file"]
<span class="js-fileapi-wrapper" style="position: relative; display: inline-block;">
<input name="files" type="file" multiple/>
</span>
Button
Stylized button.
<style>
.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;
}
</style>
<div class="js-fileapi-wrapper upload-btn">
<div class="upload-btn__txt">Upload files</div>
<input name="files" type="file" multiple />
</div>
Link
Button like link.
<style>
.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;
}
</style>
<a class="js-fileapi-wrapper upload-link">
<span class="upload-link__txt">Upload photo</span>
<input name="photo" type="file" accept="image/*" />
</a>
Installation, testing, assembling
npm install fileapi
cd fileapi
npm install
grunt
Changelog
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
Top Related Projects
File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.
The next open source file uploader for web browsers :dog:
Multiple file upload plugin with image previews, drag and drop, progress bars. S3 and Azure support, image scaling, form support, chunking, resume, pause, and tons of other features.
Dropzone is an easy to use drag'n'drop library. It supports image previews and shows nice progress bars.
A JavaScript library for providing multiple simultaneous, stable, fault-tolerant and resumable/restartable uploads via the HTML5 File API.
A JavaScript library providing multiple simultaneous, stable, fault-tolerant and resumable/restartable file uploads via the HTML5 File API.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot