具体实现如下
download(
resourceUrl: string | undefined,
targetZipPath: string,
progressCallback?: (progress: number) => void,
completeCallBack?: (isSuc: boolean, message: string) => void) {
if (resourceUrl != undefined && resourceUrl.length > 0) {
// 如果zip文件地址存在,需要先删除
if (fs.accessSync(targetZipPath)) {
fs.unlinkSync(targetZipPath)
}
try {
request.downloadFile(getContext(), { url: resourceUrl, filePath: targetZipPath })
.then((downloadTask: request.DownloadTask) => {
downloadTask.on('complete', () => {
if (progressCallback != undefined) {
progressCallback(1)
}
if (completeCallBack != undefined) {
completeCallBack(true, "下载成功")
}
})
downloadTask.on('remove', () => {
if (completeCallBack != undefined) {
completeCallBack(false, "取消下载")
}
})
downloadTask.on("progress", (receivedSize: number, totalSize: number) => {
if (progressCallback != undefined) {
let progress = receivedSize / totalSize
console.log(`下载当前进度${progress} receivedSize ${receivedSize} totalSize ${totalSize}`)
progressCallback(progress)
}
})
})
.catch((err: BusinessError) => {
if (completeCallBack != undefined) {
completeCallBack(false, err.message)
}
});
} catch (error) {
let err: BusinessError = error as BusinessError;
if (completeCallBack != undefined) {
completeCallBack(false, err.message)
}
}
} else {
if (completeCallBack != undefined) {
completeCallBack(false, "下载地址为空")
}
}
}
具体实现如下
unzipToDirectory(
zipPath: string,
targetPath: string,
progressCallback?: (progress: number) => void,
completeCallback?: (isSuc: boolean, message: string) => void) {
if (!fs.accessSync(zipPath)) {
if (completeCallback) {
completeCallback(false, "selectPath not exists");
}
return
}
if (fs.accessSync(targetPath)) {
fs.rmdirSync(targetPath)
}
fs.mkdirSync(targetPath, true);
let minizipEntry = new MinizipNative(zipPath);
let code: number = minizipEntry.Open()
if (code == 0) {
let entryNames: Array<string> = minizipEntry.GetEntryNames().sort((a: string, b: string) => {
return a.length - b.length
});
let dirEntrySet = new Set<string>()
for (let i = 0; i < entryNames.length; i++) {
const path = entryNames[i]
const index = path.lastIndexOf("/")
if (index != -1) {
const dirPath = path.substring(0, index)
dirEntrySet.add(dirPath)
}
}
let dirEntryNames = Array.from(dirEntrySet).sort((a: string, b: string) => {
return a.length - b.length
});
for (let i = 0; i < dirEntryNames.length; i++) {
let dirPath = targetPath + "/" + dirEntryNames[i]
if (!fs.accessSync(dirPath)) {
fs.mkdirSync(dirPath, true);
}
}
let onlyFiles = entryNames.filter((value) => {
return !value.endsWith("/")
})
if (progressCallback != undefined) {
progressCallback(0)
}
let result: boolean = true
for (let i = 0; i < onlyFiles.length; i++) {
let path: string = targetPath + "/" + onlyFiles[i];
let file = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
let arrBuffer: ArrayBuffer | undefined = minizipEntry.ExtractFileToJS(onlyFiles[i], "");
if (arrBuffer != undefined) {
fs.write(file.fd, arrBuffer).then((writeLen: number) => {
let progress = (i + 1) / onlyFiles.length
if (progressCallback != undefined) {
progressCallback(progress)
}
}).catch((err: BusinessError) => {
result = false
if (completeCallback) {
completeCallback(false, "fs.write failed: " + onlyFiles[i])
}
}).finally(() => {
fs.closeSync(file);
})
} else {
// 数据为空的话,直接创建空文件即可
fs.write(file.fd, "")
let progress = (i + 1) / onlyFiles.length
if (progressCallback) {
progressCallback(progress)
}
}
if (!result) {
break
}
}
if (result) {
if (progressCallback) {
progressCallback(1)
}
fs.unlink(zipPath).then(() => {
if (completeCallback) {
completeCallback(true, "unzip success")
}
})
}
} else {
if (completeCallback) {
completeCallback(false, "Open failed")
}
}
}
在加载本地网页的时候发现如果网页中的含有本地css,跳转,资源文件,都加载不出来,我们需要将上述的内容进行正则匹配后替换上述内容,再在对应的系统代理事件中进行处理
所以我们核心解决下面两个问题:
@Component
struct WebPage {
// 跳转过来 传递的地址
urlPath: string = ""
controller = new webview.WebviewController()
schemeHandler: webview.WebSchemeHandler = new webview.WebSchemeHandler();
responseWeb: WebResourceResponse = new WebResourceResponse();
fileDir: string = ""
loadData() {
try {
if (this.urlPath.includes("http") == false) {
this.loadLocalUrl()
} else {
this.controller.loadUrl(this.urlPath)
}
} catch (e) {
showShortCenterToast("加载失败")
}
}
loadLocalUrl() {
let parts = this.urlPath.split('/');
// 如果数组长度大于 1,移除最后一个元素
if (parts.length > 1) {
parts.pop();
}
// 当前H5所在文件夹的绝对路径
this.fileDir = parts.join('/')
let html = fs.readTextSync(this.urlPath)
// 要插入的指定字符串
const insertString = "http://local";
// 定义正则表达式
const regex = /src="([^"]+\.(?:png|jpg|gif))"/gi;
// 执行替换操作
const imageHtml = html.replace(regex, (_, p1: string) => {
let content = `src="${insertString}/${p1}"`;
return content
});
// href定义正则表达式
const cssRegex = /href="([^"]+\.(?:css|html))"/gi;
const cssHtml = imageHtml.replace(cssRegex, (_, p1: string) => {
let content = `href="${insertString}/${p1}"`;
return content
});
this.controller.loadData(
cssHtml,
'text/html',
'UTF-8'
);
}
build() {
Web({ src: this.urlPath, controller: this.controller })
.width(FULL_WIDTH)
.mixedMode(MixedMode.All)
.layoutWeight(1)
.onControllerAttached(() => {
this.loadData()
})
.onLoadIntercept((event) => {
let url = event.data.getRequestUrl()
// 跳转拦截
if (url.toLowerCase().startsWith('http://local') && url.toLowerCase().endsWith("html/")) {
url = url.replace("http://local", "")
url = url.toUpperCase()
url = url.replace("HTML/", "html")
const filePath = this.fileDir + "/" + url
if (fs.accessSync(filePath)) {
this.urlPath = filePath
this.loadLocalUrl()
return true
}
}
return false
})
.onInterceptRequest((event) => {
let url = event.request.getRequestUrl()
// 本地资源加载拦截
if (url.startsWith('http://local')) {
const promise: Promise<String> = new Promise((resolve: Function, reject: Function) => {
url = url.replace("http://local", "")
const filePath = this.fileDir + "/" + url
if (fs.accessSync(filePath)) {
if (url.toLowerCase().endsWith(".png") ||
url.toLowerCase().endsWith(".jpg") ||
url.toLowerCase().endsWith(".gif") ||
url.toLowerCase().endsWith(".css")) {
const fd = fs.openSync(filePath, fs.OpenMode.READ_ONLY);
// 获取文件的大小
const stat = fs.statSync(fd.fd);
const fileSize = stat.size;
// 创建一个指定大小的 ArrayBuffer
const buffer = new ArrayBuffer(fileSize);
// 读取文件内容到 ArrayBuffer
fs.readSync(fd.fd, buffer);
this.responseWeb.setResponseData(buffer);
if (url.toLowerCase().endsWith(".css")) {
this.responseWeb.setResponseMimeType('text/css');
} else {
this.responseWeb.setResponseMimeType('image/*');
}
}
this.responseWeb.setResponseCode(200);
this.responseWeb.setReasonMessage('OK');
resolve("success");
} else {
reject("failed")
}
})
promise.then(() => {
this.responseWeb.setResponseIsReady(true);
})
this.responseWeb.setResponseIsReady(false);
return this.responseWeb;
}
return null
})
.width(FULL_WIDTH)
.height(FULL_HEIGHT)
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。