Skip to content

Web API Polyfills (experimental)

wkh237 edited this page Aug 10, 2016 · 18 revisions

These APIs are still in experiment, we're trying to make file access related Web API polyfills so that browser libraries which uses Blob, File, FileReader ..etc. can still work in React Native.

XMLHttpRequest

0.8.0

Replacing window.XMLHttpRequest will break the functionality of official fetch polyfill since it's base on XMLHttpRequest polyfill. However, fetch replacement and RNFetchBlob.fetch are still working and has more features, consider use them as an alternative of fetch when using XMLHttpRequest polyfill.

Though React Native already have XMLHttpRequest polyfill, but we still can not use it with browser libraries that sending File, and Blob data. The reason is that Blob class in React Native is not completed yet. Our XMLHttpRequest polyfill has good integration with RNFetchBlob.fs API, because it uses RNFetchBlob.fetch under the hood. It contains some non-standard methods, and also some limitations which will be described in the following chapter.

Static Properties

0.8.2

binaryContentTypes:Array

An array contains MIME type string, when response Content-Type contains substring in this array, the data will be automatically converted to Blob().

Static Methods

addBinaryContentType(val:string) (NON-STANDARD)

0.8.2

Add a binaryContentType to XMLHttpRequest.binaryContentTypes.

removeBinaryContentType(val:string) (NON-STANDARD)

0.8.2

Remove a binaryContentType from XMLHttpRequest.binaryContentTypes.

Properties

readState:number (readonly)

The state of XMLHttpRequest

name value
UNSENT 0 Initial state, The object has been constructed.
OPENED 1 State after successfully invoke open(), you can setRequestHeader(), and send() during state.
HEADERS_RECEIVED 2 All redirects (if any) have been followed and all HTTP headers of the final response have been received.
LOADING 3 The request is receiving response body. Started to triggering onprogress events.
DONE 4 Response data completely received.

responseType : '' | 'blob' | 'text' | 'json'

response: string | Object | Blob

The response data, its type is decided by Content-Type in response header. This is the strategy so far :

  1. If the Content-Type field contains string text/plain the response data will be string, and XMLHttprequest.responseType will be text
  2. If the Content-Type field contains string application/json the response data will be an Object, and XMLHttprequest.responseType will be json
  3. Otherwise it would be a Blob, and XMLHttprequest.responseType will be blob

XMLHttpRequest():XMLHttpRequest

Constructor, does not accept any argument.

open(method, url, async, user, password)

method: string

url: string

async:?true (NOT IMPLEMENTED)

user:string (NOT IMPLEMENTED)

password:string (NOT IMPLEMENTED)

This method simply sets the request destination of XMLHttpRequest and change readystate to OPENED when finished.

setRequestHeader(name, value)

name: string

value: string

Set request header, this method can only be called after readstate is OPENED, otherwise it will throw an InvalidStateError.

overrideMimeType(mime)

mime: string

TODO

send(body)

body: string | Blob | Array

Send request with the given body, this method can only be called when readstate is OPENED, otherwise it will throw an InvalidStateError.

Blob

0.8.0

Blob(Binary Large Object) usually contains a reference to a binary data which stored in file, and it is used very often in HTML5 when upload and download file. Blob object can be created by directly pass an Array, ArrayBuffer, ArrayBufferView, or an array contains mix of any of such objects to its constructor. In RNFetchBlob, you can also create a Blob object from string, BASE64 encoded string, and path of a file by specifying correspond content type to the Blob object.

Properties

size:number

type:string

isRNFetchBlobPolyFill:boolean (NON-STANDARD)

Events

Static Methods

clearCache():Promise (NON-STANDARD)

This static method remove any blob files in storage, it's useful when you're going to clean up the cache folder.

build(data, options):Promise

Similar to Constructor but the Blob instance will resolved by a promise

const Blob = RNFetchBlob.polyfill.Blob
Blob.build(SOME_BASE64_ENCODED_DATA, { type: 'image/png;base64' })
    .then((blob) => {
        // do something with the Blob
    })

Constructor(data, options)

data: string | FormData | Blob | Array

options : ?{ type : string, endings : (NOT SUPPORTED) }

The content of Blob object will always stored in file system ( in DocumentDir/RNFetchBlob-blob/). You should manage these files manually. RNFetchBlob automatically decide how to store the Blob object by checking options.type and type of data. In the following steps :

  1. If type of data is a Blob, it will create a new file which copies data from given Blob object as its content.
  2. Else if the data is a String which starts with prefix RNFetchBlob-file://, it will create a new file and copies data from given file path as its content. However if it does not have the prefix, RNFetchBlob will check if options.type is a string contains application/octet or ;BASE64. If it does, create a file by decode the string using BASE64 decoder. If it does not, write the string to file as utf8 string.
  3. Else if the data is an ArrayBuffer, it will be created using the bytes in array buffer (simply applying RNFetchBlob.fs.writeFile(path, data, 'ascii')). (NOT IMPLEMENTED)
  4. Else create Blob by store the data as utf8 string text file.

Basically you can create a RNFetchBlob flavor Blob object in these way (use Blob.build)

import RNFetchBlob from 'react-native-fetch-blob'

const Blob = RNFetchBlob.polyfill.Blob

// create a blob from BASE64 encoded string, the ';base64' in `type` is crucial
Blob.build(BASE64_ENCODED_STRING, { type : 'image/png;base64' })
    .then((blob) => { ... })

// create a blob which has content of a file
Blob.build(RNFetchBlob.wrap(PATH_TO_A_FILE), { type : 'text/plain' })
    .then((blob) => { ... })

// create a blob from another blob
Blob.build('foo', { type : 'text/plain' })
    .then( (first_blob) => Blob.build(first_blob, { type : 'text/plain' }) )
    .then( (second_blob) => { ... } )

// create a blob from mice-typed array, e.g multipart form data
Blob.build(['--806254942825131805744870237569977¥r¥n',
          'Content-Type: application/json; charset=utf-8¥r¥n¥r¥n',
          '{"name":"rn-firebase-upload/image.png","contentType":"image/png"}¥r¥n',
          '--806254942825131805744870237569977¥r¥n',
          'Content-Type: image/png¥r¥n¥r¥n', 
          blob, 
          '--806254942825131805744870237569977--'
        ])
    .then((blob) => { ... })

Keep in mind that in RNFetchBlob the creation process is asynchronous, blob data becomes available after onCreated event triggered. This is not a part of Blob object standard, however this helps you create Blob object easier.

Methods

Slice(start, end, contentType) (NOT IMPLEMENTED)

TODO

onCreated(handler)

handler:(Blob) => void

Register a event handler that will be invoked when blob constructor finished the creation process, if the object already created, the handler will be invoked instantly.

close()

Remove the blob content release the resource on storage.

File

0.8.0

TODO

Clone this wiki locally