# Azure Storage JavaScript Client Library Sample for File Operations

In this sample, we will demonstrate common scenarios for Azure File Storage that includes creating, listing and deleting file shares, directories and files.

Azure File storage is a service for storing large amounts of unstructured object data, such as text or binary data, that can be accessed from anywhere in the world via HTTP or HTTPS. You can use file storage to expose data publicly to the world, or to store application data privately.

With Azure File storage, you can migrate legacy applications that rely on file shares to Azure quickly and without costly rewrites. Applications running in Azure virtual machines or cloud services or from on-premises clients can mount a file share in the cloud, just as a desktop application mounts a typical SMB share. Any number of application components can then mount and access the File storage share simultaneously. In this sample, you are able to create a file service with storage account and SAS Token. Based on the file service, you could create a file share, list files, upload files and delete files.

Note: You may need set up a HTTP server to host this sample for IE browser, because IndexedDB is only available on websites with http or https URL schemes in IE. Azure Storage JavaScript Client Library currently depends on IndexedDB.

## Contents:

- Step 1: Preparing an Azure Storage account with CORS rules set
- Step 2: Importing Azure Storage JavaScript Client Library
- Step 3: Creating an Azure Storage File Service Object
- Step 4: File Operations
- Step 5: Directory and File Operations
- Step 6: Creating your JavaScript Application based on Azure Storage JavaScript Client Library

## Step 1: Preparing an Azure Storage account with CORS rules set

Cross-origin resource sharing, or CORS, must be configured on the Azure Storage account to be accessed directly from JavaScript in the browser. You are able to set the CORS rules for specific Azure Storage account on the Azure Portal. The "Allowed origins" could be set to "*" to allow all the origins in this sample. For more information about CORS, see Cross-Origin Resource Sharing (CORS).

## Step 2: Importing Azure Storage JavaScript Files

Importing `azure-storage.common.js` and `azure-storage.file.js` in your HTML file for file operations, and make sure `azure-storage.common.js` is in front of `azure-storage.file.js`.

    <script src="azure-storage.common.js"></script>
    <script src="azure-storage.file.js"></script>

## Step 3: Creating an Azure Storage File Service Object

The `FileService` object lets you work with files and directories. Following code creates a `FileService` object with storage account and SAS Token.

    var fileUri = 'https://' + 'STORAGE_ACCOUNT' + '.file.core.windows.net';
    var fileService = AzureStorage.createFileServiceWithSas(fileUri, 'SAS_TOKEN');

In Azure Storage JavaScript Client Library, a global variable `AzureStorage` is the start point where we can create service objects for blob/table/queue/file and access to the storage utilities.

How to get full detailed API definitions? Currently, the JavaScript Client Library shares the same API definitions with Node.js SDK. Please check API details on Azure Storage Node.js API reference documents. The JavaScript global variable `AzureStorage` is just like the object `require('azure-storage')` returns in Node.js.
Warning: Azure Storage JavaScript Client Library also supports creating `FileService` based on Storage Account Key for authentication besides SAS Token. However, for security concerns, we recommend use of a limited time SAS Token, generated by a backend web server using a Stored Access Policy.

## Step 4: File Share Operations

Share: A File storage share is an SMB file share in Azure. All directories and files must be created in a parent share. An account can contain an unlimited number of shares, and a share can store an unlimited number of files, up to the 5 TB total capacity of the file share.

### List File Shares

`FileService` provides `listSharesSegmented` and `listSharesSegmentedWithPrefix` for listing file shares under a storage account.

    fileService.listSharesSegmented(null, function(error, result) {
        if(error) {
            // List shares error
        } else {
            for (var i = 0, share; share = results.entries[i]; i++) {
                // Deal with share object
            }
        }
    });

### Create File Share

`FileService` provides `createShare` and `createShareIfNotExists` for creating a file share under a storage account.

    fileService.createShareIfNotExists('myshare', function(error, result) {
        if(error) {
            // Create share error
        } else {
            // Create share successfully
        }
    });

### Delete File Share

`FileService` provides `deleteShare` and `deleteShareIfExists` for deleting a file share under a storage account.

    fileService.deleteShareIfExists('myshare', function(error, result) {
        if(error) {
            // Delete share error
        } else {
            // Delete share successfully
        }
    });

### Executable Example

The sample will try to create an Azure Storage file service object based on SAS Token authorization. Enter your Azure Storage account name and SAS Token here. Make sure you have set the CORS rules for the Azure Storage file service, and the SAS Token is in valid period.

Storage account: SAS Token:

Azure Storage file service provides plenty of interfaces for file operations. In following example, you can try to list all the file shares under your storage account, and try to create or delete one file share from your account.

- Click
  button to view the file share list under your Azure Storage account

- Click
  button to create a file share under your Azure Storage account

  New File Share Name:

- Click "Delete" button to delete the file share under your Azure Storage account

- Click "Select" button to operate with the directories and files in next step

## Step 5: Directory and File Operations

Directory in storage is an optional hierarchy of directories.

File: A file in the share. A file may be up to 1 TB in size.

### List Files and Directories

`FileService` provides `listFilesAndDirectoriesSegmented` for listing directories and files under a file share.

    fileService.listFilesAndDirectoriesSegmented('myfileshare', '', null, function(error, result, response) {
        if(error) {
            // List table entity error
        } else {
            for (var i = 0, dir; dir = results.entries.directories[i]; i++) {
                // Deal with directory object
            }
            for (var i = 0, file; file = results.entries.files[i]; i++) {
                // Deal with file object
            }
        }
    });

### Create Directory

`FileService` provides `createDirectory` and `createDirectoryIfNotExists` for creating directories under a file share.

    fileService.createDirectoryIfNotExists('myfileshare', 'mydirectory', function(error, result, response) {
        if(error) {
            // Create directory error
        } else {
            // Create directory successfully
        }
    });

### Delete Directory

`FileService` provides `deleteDirectory` and `deleteDirectoryIfExists` for deleting directories under a file share.

    fileService.deleteDirectoryIfExists('myfileshare', 'mydirectory', function(error, result, response) {
        if(error) {
            // Delete directory error
        } else {
            // Delete directory successfully
        }
    });

### Upload File

`FileService` provides `createFileFromStream` for uploading a file from stream. However, currently `createFileFromStream` only accepts a Node.js `ReadableStream` type which pure JavaScript doesn't provide.

Note: After importing `azure-storage.common.js`, you could require 3 Node.js types: `stream`, `util` and `buffer`, then wrap a ReadableStream based on HTML5 `FileReader`.

    // Provides a Stream for a file in webpage, inheriting from NodeJS Readable stream.
    var Stream = require('stream');
    var util = require('util');
    var Buffer = require('buffer').Buffer;

    function FileStream(file, opt) {
        Stream.Readable.call(this, opt);

        this.fileReader = new FileReader(file);
        this.file = file;
        this.size = file.size;
        this.chunkSize = 1024 * 1024 * 4; // 4MB
        this.offset = 0;
        var _me = this;

        this.fileReader.onloadend = function loaded(event) {
            var data = event.target.result;
            var buf = Buffer.from(data);
            _me.push(buf);
        }
    }
    util.inherits(FileStream, Stream.Readable);
    FileStream.prototype._read = function() {
        if (this.offset > this.size) {
            this.push(null);
        } else {
            var end = this.offset + this.chunkSize;
            var slice = this.file.slice(this.offset, end);
            this.fileReader.readAsArrayBuffer(slice);
            this.offset = end;
        }
    };

Uploading file from stream. You can set up the file name as well as the size of this uploading session.

    // If one file has been selected in the HTML file input element
    var files = document.getElementById('fileinput').files;
    var file = files[0];
    var fileStream = new FileStream(file);

    fileService.createFileFromStream('myfileshare', 'mydirectory', file.name, fileStream, file.size, {}, function(error, result, response) {
        if (error) {
            // Upload file failed
        } else {
            // Upload successfully
        }
    });

### Download File

`FileService` provides interfaces for downloading a file into browser memory directly. Because of browser's sandbox limitation, we cannot save the downloaded data trunks into disk until we get all the data trunks of a file into browser memory. The browser's memory size is also limited especially for downloading huge files, so it's recommended to download a file in browser with SAS Token authorized link directly.

Shared access signatures (SAS) are a secure way to provide granular access to files and directories without providing your storage account name or keys. Shared access signatures are often used to provide limited access to your data, such as allowing a mobile app to access files. The following code example generates a new shared access policy that allows the shared access signatures holder to perform read operations on the myfile file, and expires 100 minutes after the time it is created.

Note: You can choose to use the SAS Token in browser side, or generate a temporary SAS Token dynamically in your server side with Azure Storage C# or Node.js SDKs etc. according to your security requirements.

    var downloadLink = fileService.getUrl('myshare', 'mydirectory', 'myfile', 'SAS_TOKEN');

### Delete File

`FileService` provides `deleteFile` and `deleteFileIfExists` for deleting files under a file share.

    fileService.deleteFileIfExists('myfileshare', 'mydirectory', 'myfile', function(error, result, response) {
        if(error) {
            // Delete file error
        } else {
            // Delete file successfully
        }
    });

### Executable Example

After clicked the "Select" button on the file share list, you are able to operate with the directories and files under the selected file share.

- Click
  button to view the directories and files under your selected file share

- Click
  button to create a directory share under your current directory

  New Directory Name:

- Click
  button to return to upper level directory

- Click
  button to upload a local file to current directory

- Click "Delete" button to delete the directory or file

- Click "Download" link to download a file to local

Current Path:
Uploaded Bytes:
0%

### Step 6: Creating your JavaScript Application based on Azure Storage JavaScript Client Library

- 1. Setting CORS rules for your selected Azure-Storage account file service.
- 2. Including "azure-storage.common.js" in the html file.
- 3. Including functional file(s) needed, such as "azure-storage.file.js" for file operation.
- 4. Using keyword "AzureStorage" to access to Azure storage JavaScript APIs.
- 5. Referring to Azure Storage Node.js SDK documents for detailed API definitions which keep same with JavaScript APIs.

You can view the source code of this sample for detailed reference.