qb-pc-sdk 1.0.7 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -194,6 +194,110 @@ if (isBrowser && window.XMLHttpRequest && !window._qbsdkXHRBlocked) {
194
194
  window._qbsdkXHRBlocked = true;
195
195
  }
196
196
 
197
+ // 拦截 iframe 的创建,阻止加载 wxgamesdkframe.html
198
+ if (isBrowser && !window._qbsdkIframeBlocked) {
199
+ const OriginalCreateElement = document.createElement;
200
+ document.createElement = function(tagName, options) {
201
+ const element = OriginalCreateElement.call(this, tagName, options);
202
+
203
+ // 如果是 iframe,拦截 src 属性的设置
204
+ if (tagName.toLowerCase() === 'iframe') {
205
+ const originalSetAttribute = element.setAttribute;
206
+ const originalSetProperty = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'src') ||
207
+ Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype, 'src');
208
+
209
+ // 拦截 setAttribute
210
+ element.setAttribute = function(name, value) {
211
+ if (name === 'src' && value && /wxgamesdkframe/i.test(value)) {
212
+ // 阻止加载 wxgamesdkframe
213
+ return;
214
+ }
215
+ return originalSetAttribute.apply(this, arguments);
216
+ };
217
+
218
+ // 拦截 src 属性设置
219
+ if (originalSetProperty && originalSetProperty.set) {
220
+ Object.defineProperty(element, 'src', {
221
+ set: function(value) {
222
+ if (value && /wxgamesdkframe/i.test(value)) {
223
+ // 阻止加载 wxgamesdkframe
224
+ return;
225
+ }
226
+ originalSetProperty.set.call(this, value);
227
+ },
228
+ get: function() {
229
+ return originalSetProperty.get ? originalSetProperty.get.call(this) : this.getAttribute('src');
230
+ },
231
+ configurable: true
232
+ });
233
+ } else {
234
+ // 降级方案:使用 Object.defineProperty
235
+ let _src = '';
236
+ Object.defineProperty(element, 'src', {
237
+ set: function(value) {
238
+ if (value && /wxgamesdkframe/i.test(value)) {
239
+ // 阻止加载 wxgamesdkframe
240
+ return;
241
+ }
242
+ _src = value;
243
+ if (originalSetAttribute) {
244
+ originalSetAttribute.call(this, 'src', value);
245
+ }
246
+ },
247
+ get: function() {
248
+ return _src || this.getAttribute('src') || '';
249
+ },
250
+ configurable: true
251
+ });
252
+ }
253
+ }
254
+
255
+ return element;
256
+ };
257
+ window._qbsdkIframeBlocked = true;
258
+ }
259
+
260
+ // 使用 MutationObserver 监听已存在的 iframe,阻止加载 wxgamesdkframe
261
+ if (isBrowser && window.document && window.MutationObserver && !window._qbsdkObserverAdded) {
262
+ const observer = new MutationObserver(function(mutations) {
263
+ mutations.forEach(function(mutation) {
264
+ mutation.addedNodes.forEach(function(node) {
265
+ if (node.nodeType === 1 && node.tagName && node.tagName.toLowerCase() === 'iframe') {
266
+ const src = node.src || node.getAttribute('src') || '';
267
+ if (src && /wxgamesdkframe/i.test(src)) {
268
+ // 阻止加载
269
+ node.src = '';
270
+ node.setAttribute('src', '');
271
+ // 移除 iframe
272
+ try {
273
+ node.parentNode && node.parentNode.removeChild(node);
274
+ } catch (e) {
275
+ // 忽略错误
276
+ }
277
+ }
278
+ }
279
+ });
280
+ });
281
+ });
282
+
283
+ // 等待 DOM 加载完成
284
+ if (window.document.body) {
285
+ observer.observe(window.document.body, {
286
+ childList: true,
287
+ subtree: true
288
+ });
289
+ } else {
290
+ window.addEventListener('DOMContentLoaded', function() {
291
+ observer.observe(window.document.body, {
292
+ childList: true,
293
+ subtree: true
294
+ });
295
+ });
296
+ }
297
+
298
+ window._qbsdkObserverAdded = true;
299
+ }
300
+
197
301
  // 浏览器中预加载底层 SDK(仅 side-effect,挂载 window.GDTAdSDK)
198
302
  if (isBrowser) {
199
303
  try {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "qb-pc-sdk",
3
- "version": "1.0.7",
4
- "description": "趣变广告 SDK 封装器 - PC端广告接入工具,自动处理多级接口映射与原生渲染逻辑",
3
+ "version": "1.0.9",
4
+ "description": "趣变广告 SDK 封装器 - 更新正式sdk",
5
5
  "main": "index.js",
6
6
  "files": [
7
7
  "index.js",
@@ -13,6 +13,151 @@
13
13
  // 核心拦截逻辑:在 SDK 加载前彻底屏蔽 WeChat Localhost 请求
14
14
  // ============================================================
15
15
  if (isBrowser) {
16
+ // 0. 拦截 iframe 的创建,阻止加载 wxgamesdkframe.html
17
+ if (window.document && !window._qbsdkIframeBlocked) {
18
+ const OriginalCreateElement = window.document.createElement;
19
+ window.document.createElement = function(tagName, options) {
20
+ const element = OriginalCreateElement.call(this, tagName, options);
21
+
22
+ // 如果是 iframe,拦截 src 属性的设置
23
+ if (tagName.toLowerCase() === 'iframe') {
24
+ const originalSetAttribute = element.setAttribute;
25
+
26
+ // 拦截 setAttribute
27
+ element.setAttribute = function(name, value) {
28
+ if (name === 'src' && value && /wxgamesdkframe/i.test(value)) {
29
+ // 阻止加载 wxgamesdkframe
30
+ return;
31
+ }
32
+ return originalSetAttribute.apply(this, arguments);
33
+ };
34
+
35
+ // 拦截 src 属性设置
36
+ let _src = '';
37
+ Object.defineProperty(element, 'src', {
38
+ set: function(value) {
39
+ if (value && /wxgamesdkframe/i.test(value)) {
40
+ // 阻止加载 wxgamesdkframe
41
+ return;
42
+ }
43
+ _src = value;
44
+ if (originalSetAttribute) {
45
+ originalSetAttribute.call(this, 'src', value);
46
+ }
47
+
48
+ // 如果 iframe 加载完成,在其内部也设置拦截
49
+ if (value && element.contentWindow) {
50
+ try {
51
+ const iframeWindow = element.contentWindow;
52
+ if (iframeWindow && iframeWindow.XMLHttpRequest && !iframeWindow._qbsdkXHRBlocked) {
53
+ const OriginalXHR = iframeWindow.XMLHttpRequest;
54
+ iframeWindow.XMLHttpRequest = function() {
55
+ const xhr = new OriginalXHR();
56
+ const originalOpen = xhr.open;
57
+ const originalSend = xhr.send;
58
+
59
+ xhr.open = function(method, url, async, user, password) {
60
+ if (url && /localhost\.weixin\.qq\.com/i.test(url)) {
61
+ xhr._qbsdkBlocked = true;
62
+ return;
63
+ }
64
+ return originalOpen.apply(this, arguments);
65
+ };
66
+
67
+ xhr.send = function(data) {
68
+ if (xhr._qbsdkBlocked) {
69
+ return;
70
+ }
71
+ return originalSend.apply(this, arguments);
72
+ };
73
+
74
+ return xhr;
75
+ };
76
+ iframeWindow._qbsdkXHRBlocked = true;
77
+ }
78
+ } catch (e) {
79
+ // 跨域 iframe 无法访问,忽略
80
+ }
81
+ }
82
+ },
83
+ get: function() {
84
+ return _src || this.getAttribute('src') || '';
85
+ },
86
+ configurable: true
87
+ });
88
+
89
+ // 监听 iframe 加载事件,在加载后设置拦截
90
+ element.addEventListener('load', function() {
91
+ try {
92
+ const iframeWindow = element.contentWindow;
93
+ if (iframeWindow && iframeWindow.XMLHttpRequest && !iframeWindow._qbsdkXHRBlocked) {
94
+ const OriginalXHR = iframeWindow.XMLHttpRequest;
95
+ iframeWindow.XMLHttpRequest = function() {
96
+ const xhr = new OriginalXHR();
97
+ const originalOpen = xhr.open;
98
+ const originalSend = xhr.send;
99
+
100
+ xhr.open = function(method, url, async, user, password) {
101
+ if (url && /localhost\.weixin\.qq\.com/i.test(url)) {
102
+ xhr._qbsdkBlocked = true;
103
+ return;
104
+ }
105
+ return originalOpen.apply(this, arguments);
106
+ };
107
+
108
+ xhr.send = function(data) {
109
+ if (xhr._qbsdkBlocked) {
110
+ return;
111
+ }
112
+ return originalSend.apply(this, arguments);
113
+ };
114
+
115
+ return xhr;
116
+ };
117
+ iframeWindow._qbsdkXHRBlocked = true;
118
+ }
119
+ } catch (e) {
120
+ // 跨域 iframe 无法访问,忽略
121
+ }
122
+ });
123
+ }
124
+
125
+ return element;
126
+ };
127
+ window._qbsdkIframeBlocked = true;
128
+ }
129
+
130
+ // 0.1. 使用 MutationObserver 监听已存在的 iframe,阻止加载 wxgamesdkframe
131
+ if (window.document && window.MutationObserver && !window._qbsdkObserverAdded) {
132
+ const observer = new MutationObserver(function(mutations) {
133
+ mutations.forEach(function(mutation) {
134
+ mutation.addedNodes.forEach(function(node) {
135
+ if (node.nodeType === 1 && node.tagName && node.tagName.toLowerCase() === 'iframe') {
136
+ const src = node.src || node.getAttribute('src') || '';
137
+ if (src && /wxgamesdkframe/i.test(src)) {
138
+ // 阻止加载
139
+ node.src = '';
140
+ node.setAttribute('src', '');
141
+ // 移除 iframe
142
+ try {
143
+ node.parentNode && node.parentNode.removeChild(node);
144
+ } catch (e) {
145
+ // 忽略错误
146
+ }
147
+ }
148
+ }
149
+ });
150
+ });
151
+ });
152
+
153
+ observer.observe(window.document.body || window.document.documentElement, {
154
+ childList: true,
155
+ subtree: true
156
+ });
157
+
158
+ window._qbsdkObserverAdded = true;
159
+ }
160
+
16
161
  // 1. 拦截 XMLHttpRequest
17
162
  if (window.XMLHttpRequest && !window._qbsdkXHRBlocked) {
18
163
  const OriginalXHR = window.XMLHttpRequest;
@@ -140,8 +285,8 @@
140
285
 
141
286
  // 内部常量配置
142
287
  const API_CONFIG = {
143
- INIT: 'http://test.qubiankeji.com:8084/pc/init',
144
- POSITION: 'http://test.qubiankeji.com:8084/pc/position',
288
+ INIT: 'http://app.qubiankeji.com:8084/pc/init',
289
+ POSITION: 'http://app.qubiankeji.com:8084/pc/position',
145
290
  GDT_SDK_ID: 2 // 标识
146
291
  };
147
292
 
@@ -202,14 +347,33 @@
202
347
  fetch(`${API_CONFIG.POSITION}?positionId=${this.config.placementId}`).then(r => r.json())
203
348
  ]);
204
349
 
350
+ // 处理返回数据结构:支持 { data: {...} } 或直接返回数据
351
+ const initData = initRes.data || initRes;
352
+ const posData = posRes.data || posRes;
353
+
205
354
  // 2. 提取 AppID
206
- this.gdtAppId = initRes.thirdIdMap ? initRes.thirdIdMap[String(API_CONFIG.GDT_SDK_ID)] : null;
355
+ this.gdtAppId = initData.thirdIdMap ? initData.thirdIdMap[String(API_CONFIG.GDT_SDK_ID)] : null;
207
356
 
208
357
  // 3. 执行广告位筛选逻辑
209
- this.gdtPlacementId = this._selectPlacementId(posRes);
358
+ this.gdtPlacementId = this._selectPlacementId(posData);
359
+
360
+ // 添加调试日志(始终输出,便于排查问题)
361
+ console.log('[AdSDK] 初始化数据:', {
362
+ initRes: initRes,
363
+ posRes: posRes,
364
+ initData: initData,
365
+ posData: posData,
366
+ gdtAppId: this.gdtAppId,
367
+ gdtPlacementId: this.gdtPlacementId
368
+ });
210
369
 
211
370
  if (!this.gdtAppId || !this.gdtPlacementId) {
212
- throw new Error('未找到匹配的(sdkId:2)配置信息');
371
+ const errorMsg = `未找到匹配的(sdkId:2)配置信息 - AppId: ${this.gdtAppId}, PlacementId: ${this.gdtPlacementId}`;
372
+ console.error('[AdSDK]', errorMsg, {
373
+ initData: initData,
374
+ posData: posData
375
+ });
376
+ throw new Error(errorMsg);
213
377
  }
214
378
 
215
379
  this._checkAndRun();
@@ -223,21 +387,62 @@
223
387
  * 规则:headSetList优先;否则选positionSetList中优先级最高的
224
388
  */
225
389
  _selectPlacementId(data) {
390
+ if (!data) {
391
+ console.error('[AdSDK] _selectPlacementId: data 为空');
392
+ return null;
393
+ }
394
+
395
+ // 添加调试信息
396
+ console.log('[AdSDK] _selectPlacementId 输入数据:', data);
397
+ const targetSdkId = API_CONFIG.GDT_SDK_ID;
398
+ console.log('[AdSDK] 查找 sdkId (类型:', typeof targetSdkId, '值:', targetSdkId, ')');
399
+
226
400
  // A. 优先检查 headSetList
227
- if (data.headSetList && data.headSetList.length > 0) {
228
- const headAd = data.headSetList.find(item => item.sdkId === API_CONFIG.GDT_SDK_ID);
229
- if (headAd) return headAd.positionId;
401
+ if (data.headSetList && Array.isArray(data.headSetList) && data.headSetList.length > 0) {
402
+ console.log('[AdSDK] 检查 headSetList:', data.headSetList);
403
+ const headAd = data.headSetList.find(item => {
404
+ // 支持数字和字符串类型的比较
405
+ const itemSdkId = Number(item.sdkId);
406
+ const match = itemSdkId === targetSdkId || String(item.sdkId) === String(targetSdkId);
407
+ if (!match) {
408
+ console.log('[AdSDK] headSetList 项不匹配:', item, 'sdkId:', item.sdkId, '类型:', typeof item.sdkId);
409
+ }
410
+ return match;
411
+ });
412
+ if (headAd) {
413
+ console.log('[AdSDK] ✅ 在 headSetList 中找到匹配项:', headAd);
414
+ return headAd.positionId;
415
+ }
230
416
  }
231
417
 
232
418
  // B. 检查 positionSetList
233
- if (data.positionSetList && data.positionSetList.length > 0) {
419
+ if (data.positionSetList && Array.isArray(data.positionSetList) && data.positionSetList.length > 0) {
420
+ console.log('[AdSDK] 检查 positionSetList:', data.positionSetList);
234
421
  const sortedList = data.positionSetList
235
- .filter(item => item.sdkId === API_CONFIG.GDT_SDK_ID)
236
- .sort((a, b) => b.callbackPriority - a.callbackPriority); // 按优先级从大到小排序
237
-
238
- return sortedList.length > 0 ? sortedList[0].positionId : null;
422
+ .filter(item => {
423
+ // 支持数字和字符串类型的比较
424
+ const itemSdkId = Number(item.sdkId);
425
+ const match = itemSdkId === targetSdkId || String(item.sdkId) === String(targetSdkId);
426
+ console.log('[AdSDK] positionSetList 项检查:', {
427
+ item: item,
428
+ itemSdkId: item.sdkId,
429
+ itemSdkIdType: typeof item.sdkId,
430
+ targetSdkId: targetSdkId,
431
+ targetSdkIdType: typeof targetSdkId,
432
+ match: match
433
+ });
434
+ return match;
435
+ })
436
+ .sort((a, b) => (b.callbackPriority || 0) - (a.callbackPriority || 0)); // 按优先级从大到小排序
437
+
438
+ console.log('[AdSDK] 筛选后的列表:', sortedList);
439
+ if (sortedList.length > 0) {
440
+ console.log('[AdSDK] ✅ 在 positionSetList 中找到匹配项:', sortedList[0]);
441
+ return sortedList[0].positionId;
442
+ }
239
443
  }
240
444
 
445
+ console.error('[AdSDK] ❌ 未找到匹配的 sdkId:', targetSdkId, '数据:', data);
241
446
  return null;
242
447
  }
243
448
 
@@ -39,8 +39,8 @@
39
39
 
40
40
  // 初始化广告
41
41
  new window.AdSDK({
42
- appId: '1999336062823956569',
43
- placementId: '1999381081819709520',
42
+ appId: '1999364640831725629',
43
+ placementId: '2003009002186760245',
44
44
  container: '#ad-slot-1',
45
45
  onAdLoaded: () => console.log('✅ 广告加载完成'),
46
46
  onAdError: (err, msg) => console.log('❌ 广告报错:', err, msg),