Gathering detailed insights and metrics for react-native-fetch-api
Gathering detailed insights and metrics for react-native-fetch-api
Gathering detailed insights and metrics for react-native-fetch-api
Gathering detailed insights and metrics for react-native-fetch-api
npm install react-native-fetch-api
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
79 Stars
638 Commits
11 Forks
5 Watching
4 Branches
67 Contributors
Updated on 07 Nov 2024
JavaScript (100%)
Cumulative downloads
Total Downloads
Last day
6.5%
12,309
Compared to previous day
Last week
28%
66,426
Compared to previous week
Last month
-4.5%
251,188
Compared to previous month
Last year
0.3%
3,398,423
Compared to previous year
1
25
A fetch API polyfill for React Native with text streaming support
This is a fork of GitHub's fetch polyfill, the fetch implementation React Native currently provides. This project features an alternative fetch implementation directy built on top of React Native's Networking API instead of XMLHttpRequest
for performance gains. At the same time, it aims to fill in some gaps of the WHATWG specification for fetch, namely the support for text streaming.
In practice, this implementation is a drop-in replacement to GitHub's polyfill as it closely follows its implementation. Do not use this implementation if your application does not require to stream text.
GitHub's fetch polyfill, originally designed with the intention to be used in web browsers without support for the fetch standard, most notably does not support the consumption of a response body as a stream.
However, as React Native does not yet provide direct access to the underlying byte stream for responses, we either have to fallback to XMLHttpRequest or React Native's networking API for iOS and Android. Currently, only strings can be transfered through the bridge, thus binary data has to be base64-encoded (source) and while React Native's XHR provides progress events to receive incremental data, it concatenates the response string as data comes in. Although very inefficient, the response can be sliced up, each chunk encoded into its UTF-8 representation with TextEncoder and finally enqueued to the stream.
Instead of relying on XMLHttpRequest
, which degrades performance, we remove it out of the equation and have fetch interact with React Native's Networking API directly instead. To make Response.body
work, ReadableStream
's controller was integrated with native progress events. It's important to stress that progress events are only fired when the native response type is set to text
(https://github.com/facebook/react-native/blob/v0.63.4/Libraries/Network/RCTNetworking.mm#L544-L547), therefore limiting streaming to text-only transfers. If you wish to consume binary data, either blob
or base64
response types have to be used. In this case, the downside is that the final response body is read as a whole and enqueued to the stream's controller as a single chunk. There is no way to read a partial response of a binary transfer.
For more context, read the following:
Related:
React Native v0.62.0+ is the minimum version supported where the Networking API has been made public.
This implementation depends on the following web APIs which are not currently available in React Native:
It should be possible remove the dependency on TextEncoder
and TextDecoder
, but not on ReadableStream
. Either way, beware the bundle size of your application will inevitable increase.
To polyfill the above APIs, use react-native-polyfill-globals.
$ npm install react-native-fetch-api --save
The APIs provided by GitHub's implementation in React Native have to be replaced by those provided by this implementation. To do so, check and install react-native-polyfill-globals and follow the instructions therein.
No need to import anything after the setup is done. All APIs will be available globally.
Example:
1fetch('https://jsonplaceholder.typicode.com/todos/1') 2 .then(response => response.json()) 3 .then(json => console.log(json))
Check fetch's official documentation to learn more about the concepts and extended usage.
A non-standard option was added to fetch
to enable incremental events in React Native's networking layer.
1fetch('https://jsonplaceholder.typicode.com/todos/1', { reactNative: { textStreaming: true } }) 2 .then(response => response.body) 3 .then(stream => ...)
It's possible to abort an on-going request and React Native already supports AbortController
, so there is no need for a polyfill.
1const controller = new AbortController(); 2 3fetch('https://jsonplaceholder.typicode.com/todos/1', { signal: controller.signal }) 4 .then(response => response.json()) 5 .then(json => console.log(json))
Learn more about aborting fetch at https://developers.google.com/web/updates/2017/09/abortable-fetch.
There is no concept of Cross-Origin Resource Sharing (CORS) in native apps. React Native only accepts a boolean value for the credentials
option. As such, to send cookies you can either use same-origin
and include
.
The Set-Cookie
response header returned from the server is a forbidden header name and therefore can't be programmatically read with response.headers.get()
. Instead, the platform's native networking stack automatically manages cookies for you.
If you run into issues with cookie-based authentication, read the following:
Alternatively, you may consider using the react-native-cookies.
The only values supported for the cache
option are no-cache
and no-store
and Both achieve exactly the same result. All other values are ignored. Following GitHub's implementation, a cache-busting mechanism is provided by using the query parameter _
which holds the number of milliseconds elapsed since the Epoch when either no-cache
or no-store
are specified.
The fetch specification defines these values for the redirect
option: follow
(the default), error
, and manual
. React Native does not accept such option but it does transparently follow a redirect response given the Location
header for 30x status codes.
To run the test suite, you must use react-native-test-runner
CLI. Run the run-tests.js
wrapper script to spin up a local HTTP server to execute the networking tests against.
$ ./run-tests.js --platform ios --simulator '<simulator>' test/index.js
Where <simulator>
can be a combination of a device type and iOS version, e.g. iPhone 11 (14.1)
, or a device UUID.
Check which simulators are available in your system by running the following command:
$ xcrun xctrace list devices
$ ./run-tests.js --platform android --emulator '<emulator>' test/index.js
Where <emulator>
is the name of the Android Virtual Device (AVD), e.g. Pixel_API_28_AOSP
.
Check which emulators are available in your system by running the following command:
$ emulator -list-avds
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
dependency not pinned by hash detected -- score normalized to 4
Details
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
Found 1/30 approved changesets -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
security policy file not detected
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
31 existing vulnerabilities detected
Details
Score
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More