tuqin
4 天以前 d4c8ef107ad0d0835863b21f240d44402e949584
fix(map): 代理转发 Referer / Origin;诊断页增加错误来源抓取

客户复现:SDK 不报网络错误了,但弹出
「APP Referer校验失败。请检查该ak设置的白名单与访问所有的域名是否一致」(百度 error code 220)。

说明代理已生效(请求到达百度),卡在百度侧的来源校验。

服务器侧(nginx bmap-proxy.conf,9 个 location 全部覆盖):
proxy_set_header Referer $http_referer;
proxy_set_header Origin $http_origin;
nginx 默认不转发 Referer,导致百度拿不到来源 → 返回 220。

实测验证:
- 服务器本地经代理且带 Referer:SDK 874KB 正常内容
- 直接请求各 Referer 组合,B_BUSINESS_INFO 均为 business:0 / unauth:0
(说明 ak 本身未禁用,220 来自某个具体资源请求,需前端侧定位)

诊断页 bmap-test.html 新增第 4 块「错误来源抓取」:
- 重写 window.alert,捕获百度 SDK 弹出的 220 告警原文
- 包装 window.fetch,记录 /bmap-* 的 4xx/5xx 与异常
- 捕获阶段监听资源 error 事件,记录加载失败的 <img>/<script> 及 URL
用于确认 220 到底来自 SDK 本身、瓦片还是静态资源。
已修改1个文件
52 ■■■■■ 文件已修改
public/bmap-test.html 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/bmap-test.html
@@ -192,5 +192,57 @@
        document.body.appendChild(s);
      })();
    </script>
    <hr style="margin:24px 0" />
    <h3>错误来源抓取(Referer 220 定位)</h3>
    <div style="padding:8px;background:#fff2f0;border-radius:6px;font-size:13px;margin-bottom:8px">
      这一块会拦截百度 SDK 的弹窗告警,并记录所有失败请求,用来定位 220 到底来自哪个域名。
    </div>
    <div id="log4" style="padding:12px;background:#fff7e6;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('log4');
        function lg(msg, cls) {
          var t = new Date().toLocaleTimeString('zh-CN', { hour12: false });
          var d = document.createElement('div');
          d.className = cls || '';
          d.textContent = '[' + t + '] ' + msg;
          el.appendChild(d);
        }
        // 1) 拦截 alert(百度 SDK 报 220 时是弹 alert)
        var origAlert = window.alert;
        window.alert = function (msg) {
          lg('🚨 百度弹窗: ' + msg, 'bad');
          return origAlert.apply(window, arguments);
        };
        // 2) 记录所有指向 /bmap- 的失败请求
        var origFetch = window.fetch;
        if (origFetch) {
          window.fetch = function (input, init) {
            var url = typeof input === 'string' ? input : (input && input.url);
            return origFetch.apply(this, arguments).then(function (res) {
              if (!res.ok && String(url).indexOf('/bmap-') >= 0) {
                lg('fetch 失败 ' + res.status + ' ' + url, 'bad');
              }
              return res;
            }).catch(function (e) {
              if (String(url).indexOf('/bmap-') >= 0) { lg('fetch 异常 ' + url + ' : ' + e.message, 'bad'); }
              throw e;
            });
          };
        }
        // 3) 记录图片/脚本加载失败(瓦片是 img)
        document.addEventListener('error', function (e) {
          var t = e.target;
          if (!t) { return; }
          var u = t.src || t.href || '';
          if (String(u).indexOf('/bmap-') >= 0) {
            lg('资源加载失败 <' + t.tagName + '> ' + u.slice(0, 120), 'bad');
          }
        }, true);
        lg('已开始监听。现在把上面的地图块加载一遍,这里会记录失败来源。');
        lg('(如果这里没有任何记录,说明 220 来自百度 SDK 内部 alert,请看有没有「百度弹窗」行)');
      })();
    </script>
  </body>
</html>