Capacitor Android中DOMException错误修复方案咨询
问题:Cordova-Angular迁移Capacitor后Android端画布污染错误
代码片段
public async saveBlobFromMobile(blob: any, fileName: string, mimeType: string = 'image/jpeg') { console.log('saveBlobFromMobile():', mimeType); write_blob({ path: fileName, blob: blob, directory: Directory.Documents, on_fallback(error) { console.error(error); this.alert.presentToast('Ошибка записи файла', 'danger'); } }) // this.isFileLoading = false; // this.alert.presentToast('Файл сохранен в папке "Документы" (Document)'); }
错误信息
ERROR DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. at CameraPage.takeScreenshot (:997:32) at CameraPage_div_20_Template_ion_button_click_4_listener (:320:303) at executeListenerWithErrorHandling (:82745:16) at wrapListenerIn_markDirtyAndPreventDefault (:82783:22) at HostElement.<anonymous> (:106548:34) at _ZoneDelegate.invokeTask (:2750:31) at Object.onInvokeTask (:93310:33) at _ZoneDelegate.invokeTask (:2749:60) at Zone.runTask (:2522:47) at ZoneTask.invokeTask [as invoke] (https://localhost/polyfills.js:2831:34) {stack: <accessor>, code: 18, name: 'SecurityError', message: 'Failed to execute 'toDataURL' on 'HTMLCanvas…ment': Tainted canvases may not be exported.'}
环境信息
- Angular 13
- Capacitor插件:
- @capacitor-community/barcode-scanner@4.0.1
- @capacitor/filesystem@5.1.3
- capacitor-blob-writer@1.1.14
- 兼容的Android Cordova插件:
- cordova-custom-config@5.1.1
- cordova-plugin-android-permissions@1.1.5
- cordova-plugin-device@2.1.0
- cordova-plugin-file@8.0.0
- cordova-plugin-file-opener2@4.0.0
- cordova-plugin-firebase-analytics@7.0.5
- cordova-plugin-nativestorage@2.3.2
- cordova-plugin-screen-orientation@3.0.3
- cordova-plugin-statusbar@3.0.0
- cordova-sqlite-storage@6.1.0
- cordova-support-android-plugin@2.0.4
- es6-promise-plugin@4.2.2
- onesignal-cordova-plugin@3.3.1
- 不兼容且已跳过的Android Cordova插件:
- cordova-plugin-add-swift-support@2.0.2
- cordova-plugin-ionic-keyboard@2.2.0
- cordova-plugin-ionic-webview@5.0.1
- cordova-plugin-splashscreen@6.0.2
- cordova-support-google-services@1.4.1
解决方案
这个错误源于Android端WebView的安全限制,画布被跨域资源污染后无法导出内容,可通过以下方式修复:
1. 修复图片资源的跨域配置
如果Blob来自外部图片,加载时需设置crossOrigin属性:
const img = new Image(); img.crossOrigin = "anonymous"; img.src = "目标图片URL"; img.onload = () => { // 执行画布绘制操作 };
若为本地资源,确保使用Capacitor的capacitor://或file://协议路径,避免触发跨域限制。
2. 调整Android WebView网络安全配置
在android/app/src/main/res/xml/network_security_config.xml中添加本地资源访问权限:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">localhost</domain> <domain includeSubdomains="true">capacitor://localhost</domain> <domain includeSubdomains="true">file://</domain> </domain-config> </network-security-config>
在AndroidManifest.xml的application标签中引用该配置:
<application ... android:networkSecurityConfig="@xml/network_security_config">
3. 改用原生截图插件替代Canvas实现
错误栈显示问题来自takeScreenshot,使用Capacitor官方的@capacitor/screen-capture插件替换前端Canvas截图:
- 安装插件:
npm install @capacitor/screen-capture npx cap sync
- 替换截图逻辑:
import { ScreenCapture } from '@capacitor/screen-capture'; import { Filesystem, Directory } from '@capacitor/filesystem'; async takeScreenshot() { try { const captureResult = await ScreenCapture.capture(); await Filesystem.copy({ from: captureResult.path, to: "目标文件名", directory: Directory.Documents }); this.alert.presentToast('Файл сохранен в папке "Документы" (Document)'); } catch (error) { console.error(error); this.alert.presentToast('Ошибка записи файла', 'danger'); } }
4. 移除冲突的Cordova插件
Capacitor自带WebView,不兼容的cordova-plugin-ionic-webview等插件可能导致配置冲突,执行以下命令移除:
npm uninstall cordova-plugin-add-swift-support cordova-plugin-ionic-keyboard cordova-plugin-ionic-webview cordova-plugin-splashscreen cordova-support-google-services npx cap sync
内容的提问来源于stack exchange,提问作者rob1nzon
相关产品推荐
相关产品推荐

