我正在尝试学习 React Native 以及如何将文件下载到设备。我知道您可以使用反应本机文件系统来做到这一点,但这不支持我需要的身份验证。 React Native fetch blob 确实支持这一点。
出于教育目的,我希望在 React Native fetch Blob 而不是 React Native 文件系统中重新创建此问题的第一个答案中的代码。
有人可以给我写一个这样的例子,我会超级满的。
试试这个,它在 Android 上运行良好:
export const download = (url, name) => {
const { config, fs } = RNFetchBlob;
let PictureDir = fs.dirs.PictureDir;
let options = {
fileCache: true,
addAndroidDownloads: {
useDownloadManager: true,
notification: true,
path: PictureDir + name,
description: t('downloading_file')
}
};
config(options)
.fetch('GET', url)
.then(res => {
if (res.data) {
alert(t('download_success'));
} else {
alert(t('download_failed'));
}
});
};
downloadImage(){
var date = new Date();
var url = "http://debasish.com/image.jpg";
var ext = this.getExtention(url);
ext = "."+ext[0];
const { config, fs } = RNFetchBlob ;
let PictureDir = fs.dirs.PictureDir
let options = {
fileCache: true,
addAndroidDownloads : {
useDownloadManager : true,
notification : true,
path: PictureDir + "/image_"+Math.floor(date.getTime()
+ date.getSeconds() / 2)+ext,
description : 'Image'
}
}
config(options).fetch('GET', url).then((res) => {
Alert.alert("Download Success !");
});
}
getExtention(filename){
return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) :
undefined;
}
注入JS来处理blob文件下载。
const injectedJS = (function() {
window.ReactNativeWebView.postMessage = function(data) {
window.ReactNativeWebView.postMessage(JSON.stringify(data));
};
document.addEventListener('click', function(e) {
const element = e.target;
const anchor = document.querySelector('a[href^="blob:"]');
if (anchor && anchor.getAttribute('href')) {
e.preventDefault();
const xhr = new XMLHttpRequest();
let href = anchor.getAttribute('href')
const fileName = anchor.getAttribute('download') || 'downloaded-file';
fetch(href)
.then(response => response.blob())
.then(blob => {
const reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
const base64Data = reader.result.split(',')[1];
window.ReactNativeWebView.postMessage(JSON.stringify({
base64Data: base64Data,
fileName: fileName
}));
};
})
.catch(error => {
console.error('Failed to fetch blob data:', error);
});
} else {
console.log('href not loaded yet.');
}
});
})();
const handleMessage = async event => {
try {
const { base64Data, fileName } = JSON.parse(event.nativeEvent.data);
if (!base64Data) {
throw new Error('Base64 data is undefined');
}
const filePath = `${RNBlobUtil.fs.dirs.DownloadDir}/${fileName}`;
// Save the Base64 data as a file
await RNBlobUtil.fs.writeFile(filePath, base64Data, 'base64');
// Trigger a download intent on Android
await RNBlobUtil.android.actionViewIntent(filePath, 'application/pdf');
} catch (error) {
console.error('File download error:', error);
}
};
<WebView
source={{
uri
}}
allowsBackForwardNavigationGestures
bounces
cacheEnabled={false}
contentMode="mobile"
domStorageEnabled={true}
geolocationEnabled
incognito
javaScriptCanOpenWindowsAutomatically
javaScriptEnabled={true}
mixedContentMode="compatibility"
originWhitelist={['https:*', 'blob:*']}
ref={webViewRef}
scalesPageToFit
sharedCookiesEnabled
startInLoadingState={true}
style={styles.container}
thirdPartyCookiesEnabled
onLoadEnd={() => {
webViewRef.current?.injectJavaScript(injectedJS);
}}
onMessage={handleMessage}
/>