public/bmap-test.html
@@ -27,6 +27,23 @@
      #map { width: 100%; height: 320px; margin-top: 12px; border: 1px solid #ddd; }
      .tip { margin-top: 12px; padding: 10px; background: #e6f4ff; border-radius: 6px; }
    </style>
    <script>
      // 尽早注册:捕获 SDK 执行期间抛出的所有 JS 错误(这是最直接的根因线索)
      window.__bmapErr = [];
      window.addEventListener('error', function (e) {
        var t = e.target;
        if (t && (t.tagName === 'SCRIPT' || t.tagName === 'IMG' || t.tagName === 'LINK')) { return; }
        window.__bmapErr.push('JS 错误: ' + e.message + ' @' + (e.filename || '').split('/').pop() + ':' + e.lineno + ':' + e.colno);
      }, true);
      window.addEventListener('unhandledrejection', function (e) {
        window.__bmapErr.push('Promise 拒绝: ' + (e.reason && e.reason.message ? e.reason.message : e.reason));
      });
      var _ce = console.error;
      console.error = function () {
        try { window.__bmapErr.push('console.error: ' + Array.prototype.join.call(arguments, ' ').slice(0, 200)); } catch (_) {}
        return _ce.apply(console, arguments);
      };
    </script>
  </head>
  <body>
    <h3>百度地图 SDK 加载诊断</h3>
@@ -244,5 +261,229 @@
        lg('(如果这里没有任何记录,说明 220 来自百度 SDK 内部 alert,请看有没有「百度弹窗」行)');
      })();
    </script>
    <hr style="margin:24px 0" />
    <h3>环境能力检测(WebGL / XHR / 渲染)</h3>
    <div id="log5" style="padding:12px;background:#f9f0ff;border-radius:6px;font-family:Consolas,monospace;font-size:13px;line-height:1.9;white-space:pre-wrap;word-break:break-all"></div>
    <script>
      (function () {
        var el = document.getElementById('log5');
        function lg(msg, cls) {
          var d = document.createElement('div');
          d.className = cls || '';
          d.textContent = msg;
          el.appendChild(d);
        }
        lg('=== WebGL 能力 ===');
        var gl1 = null, gl2 = null;
        try {
          var c1 = document.createElement('canvas');
          gl1 = c1.getContext('webgl') || c1.getContext('experimental-webgl');
        } catch (e) { lg('WebGL1 检测异常: ' + e.message, 'bad'); }
        try {
          var c2 = document.createElement('canvas');
          gl2 = c2.getContext('webgl2');
        } catch (e) {}
        lg('WebGL 1.0: ' + (gl1 ? '✅ 支持' : '❌ 不支持'), gl1 ? 'ok' : 'bad');
        lg('WebGL 2.0: ' + (gl2 ? '✅ 支持' : '❌ 不支持'), gl2 ? 'ok' : 'warn');
        if (gl1) {
          try {
            var ext = gl1.getExtension('WEBGL_debug_renderer_info');
            if (ext) {
              lg('渲染器: ' + gl1.getParameter(ext.UNMASKED_RENDERER_WEBGL));
              lg('厂商: ' + gl1.getParameter(ext.UNMASKED_VENDOR_WEBGL));
            } else {
              lg('渲染器: ' + gl1.getParameter(gl1.RENDERER));
            }
          } catch (e) {}
        }
        lg('');
        lg('=== 其他 ===');
        lg('硬件加速(粗略): ' + (navigator.hardwareConcurrency || '?') + ' 核');
        lg('设备像素比: ' + (window.devicePixelRatio || 1));
        lg('是否远程桌面/虚拟机: 需看渲染器名称(含 SwiftShader/llvmpipe 即为软件渲染)', 'warn');
        lg('');
        lg('=== XHR 拦截(记录失败请求的真实来源)===');
        var origOpen = XMLHttpRequest.prototype.open;
        var origSend = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.open = function (m, u) {
          this.__url = u;
          return origOpen.apply(this, arguments);
        };
        XMLHttpRequest.prototype.send = function () {
          var xhr = this;
          xhr.addEventListener('loadend', function () {
            if (xhr.status === 0 || xhr.status >= 400) {
              lg('❌ XHR ' + (xhr.status || '失败') + ' ' + String(xhr.__url).slice(0, 150), 'bad');
            }
          });
          return origSend.apply(this, arguments);
        };
        lg('已开始拦截 XHR。请刷新页面看完整记录。');
        // 3 秒后检查地图容器里的实际内容
        setTimeout(function () {
          var m = document.getElementById('map3');
          if (!m) { return; }
          lg('');
          lg('=== 地图容器实际内容 ===');
          lg('innerHTML 长度: ' + m.innerHTML.length);
          lg('canvas 数量: ' + m.querySelectorAll('canvas').length);
          lg('子元素: ' + m.children.length);
          lg('尺寸: ' + m.offsetWidth + ' x ' + m.offsetHeight);
        }, 5000);
      })();
    </script>
    <hr style="margin:24px 0" />
    <h3>深度探测(SDK 完整性 / 实例行为 / 全部网络请求)</h3>
    <div id="log6" style="padding:12px;background:#e6fffb;border-radius:6px;font-family:Consolas,monospace;font-size:13px;line-height:1.9;white-space:pre-wrap;word-break:break-all"></div>
    <div id="probe-map" style="width:400px;height:300px;border:1px solid #ccc;margin-top:8px"></div>
    <script>
      (function () {
        var el = document.getElementById('log6');
        function lg(msg, cls) {
          var d = document.createElement('div');
          d.className = cls || '';
          d.textContent = msg;
          el.appendChild(d);
        }
        lg('=== 1. BMapGL 对象完整性 ===');
        lg('typeof window.BMapGL = ' + typeof window.BMapGL);
        if (window.BMapGL) {
          lg('BMapGL.Map   = ' + typeof window.BMapGL.Map);
          lg('BMapGL.Point = ' + typeof window.BMapGL.Point);
          lg('BMapGL.Marker= ' + typeof window.BMapGL.Marker);
          lg('BMapGL.Circle= ' + typeof window.BMapGL.Circle);
          lg('BMapGL.Geocoder = ' + typeof window.BMapGL.Geocoder);
          lg('BMapGL.Version = ' + (window.BMapGL.Version || window.BMapGL.version || '(无)'));
          var keys = Object.keys(window.BMapGL);
          lg('BMapGL 属性数量: ' + keys.length);
          lg('前 20 个: ' + keys.slice(0, 20).join(', '));
        }
        lg('');
        lg('=== 2. 新建一个纯净容器,创建地图后立即检查 ===');
        var div = document.getElementById('probe-map');
        try {
          var t0 = Date.now();
          var m = new window.BMapGL.Map(div);
          lg('new BMapGL.Map() 返回类型: ' + typeof m + '(耗时 ' + (Date.now() - t0) + 'ms)', 'ok');
          lg('容器 innerHTML 长度(立即): ' + div.innerHTML.length, div.innerHTML.length > 0 ? 'ok' : 'bad');
          lg('容器 children 数量: ' + div.children.length, div.children.length > 0 ? 'ok' : 'bad');
          lg('容器 outerHTML 前 300: ' + div.outerHTML.slice(0, 300));
          lg('map.getSize() = ' + JSON.stringify(m.getSize ? m.getSize() : null));
          lg('map.getCenter() = ' + (m.getCenter ? JSON.stringify(m.getCenter()) : 'null'));
          try {
            m.centerAndZoom(new window.BMapGL.Point(87.616848, 43.825592), 14);
            lg('centerAndZoom 调用成功', 'ok');
          } catch (e2) {
            lg('centerAndZoom 异常: ' + e2.message, 'bad');
          }
          setTimeout(function () {
            lg('1 秒后容器 innerHTML 长度: ' + div.innerHTML.length, div.innerHTML.length > 0 ? 'ok' : 'bad');
            lg('1 秒后 canvas 数量: ' + div.querySelectorAll('canvas').length);
          }, 1000);
        } catch (e) {
          lg('创建地图抛异常: ' + e.message, 'bad');
          lg('堆栈: ' + (e.stack || '').slice(0, 300), 'bad');
        }
        lg('');
        lg('=== 3. 页面实际发出的全部网络请求(performance API)===');
        setTimeout(function () {
          var rs = performance.getEntriesByType('resource');
          lg('总资源请求: ' + rs.length);
          var bm = rs.filter(function (r) { return r.name.indexOf('bmap') >= 0 || r.name.indexOf('baidu') >= 0; });
          lg('bmap/baidu 相关: ' + bm.length);
          bm.forEach(function (r) {
            var size = r.transferSize || r.encodedBodySize || 0;
            var st = r.responseStatus || (size > 0 ? 200 : '?');
            lg('  [' + st + '] ' + Math.round(r.duration) + 'ms ' + size + 'B  ' + r.name.replace(location.origin, '').slice(0, 110), size > 0 ? '' : 'warn');
          });
          lg('');
          lg('=== 4. 控制台错误捕获 ===');
          lg('(如上方无异常,说明 SDK 静默失败,重点看第 3 节哪些请求 0 字节)');
        }, 6000);
      })();
    </script>
    <hr style="margin:24px 0" />
    <h3>第 7 块:JS 执行错误 + 2D 版地图(不依赖 WebGL)</h3>
    <div id="log7" style="padding:12px;background:#fcffe6;border-radius:6px;font-family:Consolas,monospace;font-size:13px;line-height:1.9;white-space:pre-wrap;word-break:break-all"></div>
    <div id="map4" style="width:100%;height:340px;margin-top:12px;border:1px solid #ddd"></div>
    <script>
      (function () {
        var el = document.getElementById('log7');
        function lg(msg, cls) { var d = document.createElement('div'); d.className = cls || ''; d.textContent = msg; el.appendChild(d); }
        setTimeout(function () {
          lg('=== 捕获到的 JS 执行错误 ===');
          if (!window.__bmapErr || window.__bmapErr.length === 0) {
            lg('(无 JS 错误)', 'ok');
          } else {
            window.__bmapErr.slice(0, 15).forEach(function (m) { lg(m, 'bad'); });
          }
        }, 3000);
        lg('');
        lg('=== 2D 版地图(BMap,不使用 WebGL / Worker)===');
        var s = document.createElement('script');
        s.src = '/bmap-api/getscript?v=3.0&ak=' + KEY + '&services=&t=' + Date.now();
        s.addEventListener('load', function () {
          lg('load 触发,window.BMap = ' + typeof window.BMap, window.BMap ? 'ok' : 'bad');
          if (!window.BMap) { return; }
          try {
            var map = new window.BMap.Map('map4');
            map.centerAndZoom(new window.BMap.Point(87.616848, 43.825592), 14);
            map.enableScrollWheelZoom(true);
            lg('地图创建成功', 'ok');
            setTimeout(function () {
              var d = document.getElementById('map4');
              lg('容器 innerHTML 长度: ' + d.innerHTML.length, d.innerHTML.length > 0 ? 'ok' : 'bad');
              lg('容器内 img 数量: ' + d.querySelectorAll('img').length);
              lg('👉 如果这里能看到乌鲁木齐街道,说明 2D 版可用,我立即切过去', 'ok');
            }, 3000);
          } catch (e) {
            lg('创建 2D 地图异常: ' + e.message, 'bad');
          }
        });
        s.addEventListener('error', function () { lg('2D SDK 加载失败', 'bad'); });
        document.body.appendChild(s);
      })();
    </script>
    <hr style="margin:24px 0" />
    <h3>第 8 块:2D 版改写 SDK(瓦片也走代理,无 Worker)</h3>
    <div id="log8" style="padding:12px;background:#f0f5ff;border-radius:6px;font-family:Consolas,monospace;font-size:13px;line-height:1.9;white-space:pre-wrap;word-break:break-all"></div>
    <div id="map5" style="width:100%;height:340px;margin-top:12px;border:1px solid #ddd"></div>
    <script>
      (function () {
        var el = document.getElementById('log8');
        function lg(m, c) { var d = document.createElement('div'); d.className = c || ''; d.textContent = m; el.appendChild(d); }
        lg('加载 /bmap-sdk2d.js(2D 改写版,瓦片走 /bmap-tileN)...');
        var s = document.createElement('script');
        s.src = '/bmap-sdk2d.js';
        s.addEventListener('load', function () {
          lg('load 触发,window.BMap = ' + typeof window.BMap, window.BMap ? 'ok' : 'bad');
          if (!window.BMap) { return; }
          try {
            var map = new window.BMap.Map('map5');
            map.centerAndZoom(new window.BMap.Point(87.616848, 43.825592), 14);
            map.enableScrollWheelZoom(true);
            lg('2D 地图创建成功', 'ok');
            setTimeout(function () {
              var d = document.getElementById('map5');
              lg('容器 innerHTML: ' + d.innerHTML.length);
              lg('img 数量: ' + d.querySelectorAll('img').length, d.querySelectorAll('img').length > 0 ? 'ok' : 'bad');
              lg('👉 能看到的街道就说明 2D 改写版可用', 'ok');
            }, 4000);
          } catch (e) { lg('创建异常: ' + e.message, 'bad'); }
        });
        s.addEventListener('error', function () { lg('加载失败', 'bad'); });
        document.body.appendChild(s);
      })();
    </script>
  </body>
</html>