m0_72460262 2025-09-29 17:21 采纳率: 0%
浏览 3

Flutter WebView 集成 WebAR (A-Frame + MindAR) 在 Android 上偶发 net::ERR_NAME_NOT_RESOLVED

Flutter WebView 集成 WebAR (A-Frame + MindAR) 在 Android 上偶发 net::ERR_NAME_NOT_RESOLVED,如何彻底本地化子资源?


我在做一个 Flutter WebAR 项目(技术栈:Flutter WebView + A-Frame + MindAR)。

运行环境:

  • Flutter 3.x

  • 插件:webview_flutter (v4)

  • Android 13 / 小米手机

  • 入口页面通过 appassets 加载:

    https://appassets.androidplatform.net/assets/flutter_assets/assets/webar/index.html
    

问题现象

  • 主文档能成功加载(index.html 在 appassets 下)。
  • HUD 注入策略已改为 pending → arReady 再贴,确认不是被 A-Frame 画布遮挡。
  • 日志中仍然会报子资源失败:
I/flutter: [网络][错误] 资源加载失败 | ctx={"错误码":-2,"描述":"DNS 解析失败(ERR_NAME_NOT_RESOLVED)","是否主框架":false}

这说明仍有某些子资源在尝试访问外域,但我已经把核心库(A-Frame/MindAR)、.mind 文件、GLB 模型等都放到本地 assets/ 路径下。


关键代码片段

1. Flutter WebView 网络错误回调(webar_page.dart

NavigationDelegate _buildNavigationDelegate() {
  return NavigationDelegate(
    onWebResourceError: (err) async {
      // ✅ 打印 failingUrl,确认是哪条资源出网
      debugPrint('[WebAR][NET][error] failingUrl=${err.failingUrl}, '
          'isMainFrame=${err.isForMainFrame}, '
          'code=${err.errorCode}, '
          'desc=${err.description}');
    },
  );
}

2. utils.js —— 路径统一 & HUD 占位

// English code; 中文备注:统一把 assets/* 转 appassets,同源访问
function resolveAssetPath(rel) {
  if (!rel) return '';
  if (/^https?:\/\//i.test(rel) || /^file:\/\//i.test(rel)) return rel;
  rel = String(rel).replace(/^\/+/, '');
  return 'https://appassets.androidplatform.net/assets/flutter_assets/' + rel;
}

// English code; 中文备注:预置 setOverlay 占位,避免 Dart 早注入失败
if (typeof window.setOverlay !== 'function') {
  window.setOverlay = function(cfg){
    window.__overlayPending = cfg || null; // 中文:先存起来,业务脚本就绪后再贴
  };
}

3. index.html —— 本地加载 A-Frame/MindAR 启动器

<script>
(function(){
  function load(url){
    return new Promise(function(res, rej){
      var s = document.createElement('script');
      s.src = url;
      s.onload = res;
      s.onerror = function(){ console.error('[boot] load failed:', url); rej(); };
      document.head.appendChild(s);
    });
  }
  function r(p){ return (typeof resolveAssetPath==='function') ? resolveAssetPath(p) : p; }

  async function loadLocalLibs(){
    await load(r('assets/webar/libs/aframe.min.js'));
    await load(r('assets/webar/libs/mindar-image-aframe.prod.js'));
    console.log('[boot] local A-Frame/MindAR ready');
  }
  loadLocalLibs();
})();
</script>

4. mindar.js —— .mind 初始化与候选回退

// 初始 imageTargetSrc
var mindUrl = (typeof resolveAssetPath === 'function')
  ? resolveAssetPath('assets/mindar/1.mind')
  : 'assets/mindar/1.mind';
if (scene) scene.setAttribute('mindar-image', 'imageTargetSrc: ' + mindUrl);

// arReady 时探测候选文件
(async function(){
  const candidates = [
    resolveAssetPath('assets/mindar/2.mind'),
    resolveAssetPath('assets/mindar/1.mind')
  ];
  for (const url of candidates) {
    try {
      const r = await fetch(url, { method: 'HEAD' });
      if (r.ok) {
        scene.setAttribute('mindar-image', 'imageTargetSrc: ' + url);
        return;
      }
    } catch(e){ console.error('[Assets] .mind fetch error:', e); }
  }
  console.error('[Assets] no valid .mind found.');
})();

我的疑问

  1. 既然核心库和资源都已本地化,为什么 WebView 仍然会有子资源访问外域?

    • 可能是 GLB 模型内部的贴图 URI?
    • 还是 CSS 字体/背景?
    • 或者 MindAR 内部还尝试访问 CDN?
  2. 有没有办法在 WebView 或页面层面拦截所有请求 URL,快速确认是哪条资源还在出网?


问题

有没有朋友遇到过类似情况?如何保证 完全离线运行,避免任何 net::ERR_NAME_NOT_RESOLVED 的子资源错误?


👉 以上就是我最小化后的代码和日志,如果有经验的同学能帮忙看看还有哪些“隐性资源”需要本地化,非常感谢!


  • 写回答

4条回答 默认 最新

  • 阿里嘎多学长 2025-09-29 17:21
    关注

    阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程

    问题解决方案

    网络请求异常 net::ERR_NAME_NOT_RESOLVED 解决方法:

    1. 检查域名拼写错误:确保域名正确无误,包括子域名和文件路径。

    2. 检查网络连接: 确保手机与 Wi-Fi 或移动网络连接正常。

    3. 检查 WebView 配置: 确保 WebView 配置正确,特别是域名前缀和白名单。

    4. 尝试本地化资源:尝试将相关资源从服务器下载到本地,避免 DNS 解析过程中的错误。

    5. 检查 AndroidManifest.xml 文件:确保 AndroidManifest.xml 中的android:networkSecurityConfig配置正确无误。

    具体实现如下(AndroidManifest.xml 文件中加入 networkSecurityConfig 配置):

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="your.package.name">
        ...
        <application
            ...
            android:networkSecurityConfig="@xml/network_security_config"
            ...>
            ...
        </application>
    </manifest>
    

    network_security_config.xml 文件:

    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <domain-config>
            <domain includeSubdomains="true"">example.com</domain>
            <!-- 如果不确定域名,则配置全部域名 -->
            <domain includeSubdomains="true">*</domain>
        </domain-config>
    </network-security-config>
    
    1. 检查 Java 代码:确保 Java 代码中使用的网络请求逻辑正确无误。

    以上解决方案可以帮助您解决 Flutter WebView 集成 WebAR (A-Frame + MindAR) 在 Android 上的 net::ERR_NAME_NOT_RESOLVED 异常问题。

    评论

报告相同问题?

问题事件

  • 创建了问题 9月29日