crh-jssdk 1.0.31 → 1.0.32

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.
@@ -78,8 +78,7 @@ var JYClientTHS = {
78
78
  },
79
79
  /**
80
80
  * 连接WebViewJavascriptBridge
81
- * 仅依赖 WebViewJavascriptBridgeReady 事件,不使用 iframe 注入方式
82
- * 原因:WVJBCallbacks 已在脚本顶层立即初始化,确保 native _callWVJBCallbacks 调用时数组始终存在
81
+ * 支持重新注入机制:从第三方页面返回后,iOS WebView可能需要通过iframe触发bridge重新注入
83
82
  */
84
83
  connectWebViewJavascriptBridge: function (callback) {
85
84
  // 如果Bridge已存在,直接使用
@@ -87,13 +86,29 @@ var JYClientTHS = {
87
86
  callback(window.WebViewJavascriptBridge);
88
87
  return;
89
88
  }
90
- // iOS设备:监听BridgeReady事件,不再使用iframe触发
89
+ // iOS设备:优先尝试通过 iframe 触发 bridge 重新注入
90
+ // 这样可以处理从第三方页面返回后 bridge 失效的问题
91
91
  if (!/Android/.test(navigator.userAgent)) {
92
+ console.log('[ClientTHS] iOS设备,尝试通过iframe触发bridge注入');
93
+ this._injectBridgeViaIframe();
92
94
  // 监听BridgeReady事件
95
+ document.addEventListener('WebViewJavascriptBridgeReady', function () {
96
+ console.log('[ClientTHS] WebViewJavascriptBridgeReady 事件触发');
97
+ callback(window.WebViewJavascriptBridge);
98
+ }, false);
99
+ // WVJBCallbacks 用于 native 调用 JS 时找到回调函数
100
+ if (window.WVJBCallbacks) {
101
+ window.WVJBCallbacks.push(callback);
102
+ }
103
+ else {
104
+ window.WVJBCallbacks = [callback];
105
+ }
106
+ }
107
+ else {
108
+ // Android设备:直接监听事件
93
109
  document.addEventListener('WebViewJavascriptBridgeReady', function () {
94
110
  callback(window.WebViewJavascriptBridge);
95
111
  }, false);
96
- // WVJBCallbacks 已在脚本顶层初始化,此处直接 push 即可
97
112
  if (window.WVJBCallbacks) {
98
113
  window.WVJBCallbacks.push(callback);
99
114
  }
@@ -102,6 +117,34 @@ var JYClientTHS = {
102
117
  }
103
118
  }
104
119
  },
120
+ /**
121
+ * 通过 iframe 触发 iOS WebViewJavaScriptBridge 重新注入
122
+ * 标准 iOS WVJB 注入方式(官方 demo 使用 wvjbscheme://__BRIDGE_LOADED__)
123
+ */
124
+ _injectBridgeViaIframe: function () {
125
+ try {
126
+ var iframe_1 = document.createElement('iframe');
127
+ iframe_1.style.display = 'none';
128
+ // iOS 原生拦截此 URL 触发 bridge 重新注入(官方标准方式)
129
+ iframe_1.src = 'wvjbscheme://__BRIDGE_LOADED__';
130
+ document.documentElement.appendChild(iframe_1);
131
+ console.log('[ClientTHS] iframe 已创建用于触发 bridge 重新注入');
132
+ // 立即清理 iframe
133
+ setTimeout(function () {
134
+ try {
135
+ if (iframe_1.parentNode) {
136
+ iframe_1.parentNode.removeChild(iframe_1);
137
+ }
138
+ }
139
+ catch (e) {
140
+ // ignore
141
+ }
142
+ }, 0);
143
+ }
144
+ catch (e) {
145
+ console.error('[ClientTHS] iframe 创建失败:', e);
146
+ }
147
+ },
105
148
  /**
106
149
  * 调用App方法
107
150
  * 与ClientTemplate.js保持一致
@@ -157,85 +200,22 @@ var JYBridge = /** @class */ (function () {
157
200
  function JYBridge() {
158
201
  this.bridge = null;
159
202
  this.initPromise = null;
160
- // 标记Bridge是否已知有效(首次成功调用后标记为true)
161
- this._bridgeVerified = false;
162
203
  this.initPromise = this.init();
163
204
  }
164
- /**
165
- * 检查Bridge是否真正可用
166
- * 原因:从第三方页面返回时,iOS WebView可能重建,导致缓存的bridge引用失效
167
- * @returns {boolean}
168
- */
169
- JYBridge.prototype.isBridgeAvailable = function () {
170
- // 检查 window.WebViewJavascriptBridge 是否存在
171
- if (!window.WebViewJavascriptBridge) {
172
- console.warn('[JYBridge] Bridge不存在,需要重新连接');
173
- return false;
174
- }
175
- // 检查 bridge 对象是否有 callHandler 方法
176
- var wb = window.WebViewJavascriptBridge;
177
- if (typeof wb.callHandler !== 'function') {
178
- console.warn('[JYBridge] Bridge.callHandler方法不存在,可能已失效');
179
- return false;
180
- }
181
- // 如果之前验证过bridge有效,标记为可用
182
- if (this._bridgeVerified && this.bridge) {
183
- return true;
184
- }
185
- // 如果之前没验证过,但bridge存在,也认为可用(首次连接)
186
- return true;
187
- };
188
- /**
189
- * 主动重连Bridge
190
- * 从第三方页面返回后调用此方法重置Bridge连接状态
191
- * @returns {Promise<void>}
192
- */
193
- JYBridge.prototype.reconnect = function () {
194
- return __awaiter(this, void 0, void 0, function () {
195
- return __generator(this, function (_a) {
196
- switch (_a.label) {
197
- case 0:
198
- console.log('[JYBridge] 开始重连Bridge...');
199
- // 重置状态
200
- this._bridgeVerified = false;
201
- this.bridge = null;
202
- this.initPromise = null;
203
- // 重新初始化
204
- this.initPromise = this.init();
205
- return [4 /*yield*/, this.initPromise];
206
- case 1:
207
- _a.sent();
208
- console.log('[JYBridge] Bridge重连完成');
209
- return [2 /*return*/];
210
- }
211
- });
212
- });
213
- };
214
205
  /**
215
206
  * 初始化Bridge连接
216
207
  * 使用ClientTHS初始化方式
217
- * 注意:从第三方页面返回时 WebView 可能被重建,Bridge 尚未注入,需配合 iframe 触发重新注入
218
208
  */
219
209
  JYBridge.prototype.init = function () {
220
210
  var _this = this;
221
211
  return new Promise(function (resolve) {
222
212
  // 使用ClientTHS初始化(与ClientTemplate.js一致)
223
213
  JYClientTHS.init();
224
- var checkCount = 0;
225
- // 最多等待30秒(300次 * 100ms),超时后不再等待
226
- var maxChecks = 30;
227
214
  // 等待WebViewJavascriptBridgeReady事件
228
215
  var checkBridge = function () {
229
- checkCount++;
230
216
  if (window.WebViewJavascriptBridge) {
231
217
  _this.bridge = window.WebViewJavascriptBridge;
232
- _this._bridgeVerified = true; // 标记为已验证
233
- console.log('[JYBridge] 初始化完成,bridge已验证');
234
- resolve();
235
- }
236
- else if (checkCount >= maxChecks) {
237
- // 超时,不再等待
238
- console.warn('[JYBridge] 初始化超时(3秒),停止等待');
218
+ console.log('JYBridge 初始化完成');
239
219
  resolve();
240
220
  }
241
221
  else {
@@ -252,66 +232,24 @@ var JYBridge = /** @class */ (function () {
252
232
  * @param params 参数
253
233
  */
254
234
  JYBridge.prototype.bridgeCallHandler = function (type, name, params) {
255
- var _this = this;
256
235
  if (type === void 0) { type = ''; }
257
236
  if (name === void 0) { name = ''; }
258
237
  if (params === void 0) { params = {}; }
259
238
  if (type === 'Promise') {
260
239
  return new Promise(function (resolve, reject) {
261
- // 构造超时 reject 函数,避免重复定义
262
- var timeoutReject = function () {
263
- reject(new Error("\u8C03\u7528".concat(name, "\u65B9\u6CD5\u8D85\u65F6\uFF0810\u79D2\uFF09\uFF0CBridge\u53EF\u80FD\u4E0D\u53EF\u7528")));
264
- };
265
- // 设置10秒超时
266
- var timeoutId = setTimeout(timeoutReject, 10000);
267
240
  try {
268
- // 等待Bridge初始化完成后再执行
269
- _this.waitForReady(300)
270
- .then(function () {
271
- // 调用前检查Bridge是否真正可用
272
- if (!_this.isBridgeAvailable()) {
273
- console.warn('[JYBridge] Bridge不可用,尝试重连...');
274
- // 尝试重连
275
- return _this.reconnect().then(function () {
276
- // 重连后再次检查
277
- if (!_this.isBridgeAvailable()) {
278
- clearTimeout(timeoutId);
279
- reject(new Error('Bridge重连后仍不可用,请从App重新进入页面'));
280
- return;
281
- }
282
- // 执行调用
283
- _this.doBridgeCall(name, params, resolve, reject, timeoutId);
284
- });
241
+ JYClientTHS.bridgeCallHandler(name, params, function (response) {
242
+ // 只要有响应就 resolve,即使是空对象或只有 login_status
243
+ // getUserInfoByRsa 未登录时返回 { login_status: "0" }
244
+ if (response !== undefined && response !== null) {
245
+ resolve(response);
246
+ }
247
+ else {
248
+ reject(new Error("\u8C03\u7528".concat(name, "\u65B9\u6CD5\u5931\u8D25\u4E86!")));
285
249
  }
286
- // Bridge可用,执行调用
287
- _this.doBridgeCall(name, params, resolve, reject, timeoutId);
288
- })
289
- .catch(function () {
290
- // waitForReady 超时,尝试直接连接
291
- console.warn('[JYBridge] waitForReady超时,尝试直接连接...');
292
- JYClientTHS.connectWebViewJavascriptBridge(function (bridge) {
293
- if (bridge && typeof bridge.callHandler === 'function') {
294
- _this.bridge = bridge;
295
- _this._bridgeVerified = true;
296
- bridge.callHandler(name, params, function (response) {
297
- clearTimeout(timeoutId);
298
- if (response !== undefined && response !== null) {
299
- resolve(response);
300
- }
301
- else {
302
- reject(new Error("\u8C03\u7528".concat(name, "\u65B9\u6CD5\u5931\u8D25\u4E86!")));
303
- }
304
- });
305
- }
306
- else {
307
- clearTimeout(timeoutId);
308
- reject(new Error('Bridge不可用,请从App重新进入页面'));
309
- }
310
- });
311
250
  });
312
251
  }
313
252
  catch (e) {
314
- clearTimeout(timeoutId);
315
253
  reject(e);
316
254
  }
317
255
  });
@@ -325,29 +263,6 @@ var JYBridge = /** @class */ (function () {
325
263
  }
326
264
  return Promise.resolve();
327
265
  };
328
- /**
329
- * 执行Bridge调用
330
- * @param name 方法名
331
- * @param params 参数
332
- * @param resolve Promise resolve
333
- * @param reject Promise reject
334
- * @param timeoutId 超时计时器ID
335
- */
336
- JYBridge.prototype.doBridgeCall = function (name, params, resolve, reject, timeoutId) {
337
- var _this = this;
338
- JYClientTHS.bridgeCallHandler(name, params, function (response) {
339
- clearTimeout(timeoutId);
340
- // 只要有响应就 resolve,即使是空对象或只有 login_status
341
- // getUserInfoByRsa 未登录时返回 { login_status: "0" }
342
- if (response !== undefined && response !== null) {
343
- _this._bridgeVerified = true; // 标记为已验证可用
344
- resolve(response);
345
- }
346
- else {
347
- reject(new Error("\u8C03\u7528".concat(name, "\u65B9\u6CD5\u5931\u8D25\u4E86!")));
348
- }
349
- });
350
- };
351
266
  /**
352
267
  * 调用App方法(纯回调版本,不返回Promise)
353
268
  * @param name 方法名
@@ -386,16 +301,64 @@ var JYBridge = /** @class */ (function () {
386
301
  * 检查Bridge是否已初始化
387
302
  */
388
303
  JYBridge.prototype.isReady = function () {
389
- return !!this.bridge && this.isBridgeAvailable();
304
+ return !!this.bridge;
305
+ };
306
+ /**
307
+ * 检查Bridge是否真正可用
308
+ * 原因:从第三方页面返回时,iOS WebView可能重建,导致缓存的bridge引用失效
309
+ * @returns {boolean}
310
+ */
311
+ JYBridge.prototype.isBridgeAvailable = function () {
312
+ // 检查 window.WebViewJavascriptBridge 是否存在
313
+ if (!window.WebViewJavascriptBridge) {
314
+ console.warn('[JYBridge] Bridge不存在,需要重新连接');
315
+ return false;
316
+ }
317
+ // 检查 bridge 对象是否有 callHandler 方法
318
+ var wb = window.WebViewJavascriptBridge;
319
+ if (typeof wb.callHandler !== 'function') {
320
+ console.warn('[JYBridge] Bridge.callHandler方法不存在,可能已失效');
321
+ return false;
322
+ }
323
+ return true;
324
+ };
325
+ /**
326
+ * 主动重连Bridge
327
+ * 从第三方页面返回后调用此方法重置Bridge连接状态
328
+ * 使用 iframe 触发 iOS WebViewJavaScriptBridge 重新注入
329
+ * @returns {Promise<void>}
330
+ */
331
+ JYBridge.prototype.reconnect = function () {
332
+ return __awaiter(this, void 0, void 0, function () {
333
+ return __generator(this, function (_a) {
334
+ switch (_a.label) {
335
+ case 0:
336
+ console.log('[JYBridge] 开始重连Bridge...');
337
+ // 重置状态
338
+ this.bridge = null;
339
+ // 对于 iOS 设备,使用 iframe 触发 bridge 重新注入
340
+ // 这是 iOS WebViewJavaScriptBridge 的标准用法(官方demo使用 wvjbscheme://__BRIDGE_LOADED__)
341
+ if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
342
+ console.log('[JYBridge] iOS设备,使用iframe触发bridge重新注入');
343
+ JYClientTHS._injectBridgeViaIframe();
344
+ }
345
+ // 重新初始化
346
+ this.initPromise = this.init();
347
+ return [4 /*yield*/, this.initPromise];
348
+ case 1:
349
+ _a.sent();
350
+ console.log('[JYBridge] Bridge重连完成');
351
+ return [2 /*return*/];
352
+ }
353
+ });
354
+ });
390
355
  };
391
356
  /**
392
357
  * 等待Bridge准备就绪
393
- * 如果Bridge不可用,会尝试重连
394
358
  */
395
359
  JYBridge.prototype.waitForReady = function (timeout) {
396
- var _this = this;
397
360
  if (timeout === void 0) { timeout = 300; }
398
- // 如果Bridge存在且可用,直接返回
361
+ // 如果Bridge可用,直接返回
399
362
  if (this.bridge && this.isBridgeAvailable()) {
400
363
  return Promise.resolve();
401
364
  }
@@ -403,26 +366,10 @@ var JYBridge = /** @class */ (function () {
403
366
  if (this.bridge && !this.isBridgeAvailable()) {
404
367
  console.warn('[JYBridge] Bridge不可用,尝试自动重连...');
405
368
  return this.reconnect()
406
- .then(function () {
407
- if (_this.bridge && _this.isBridgeAvailable()) {
408
- return Promise.resolve();
409
- }
410
- // 重连后仍然不可用,等待初始化的Promise
411
- if (_this.initPromise) {
412
- return Promise.race([
413
- _this.initPromise,
414
- new Promise(function (_, reject) {
415
- setTimeout(function () { return reject(new Error('JYBridge重连后初始化超时')); }, timeout);
416
- })
417
- ]);
418
- }
419
- return Promise.resolve();
420
- })
421
- .catch(function () {
422
- return Promise.reject(new Error('JYBridge重连失败'));
423
- });
369
+ .then(function () { return Promise.resolve(); })
370
+ .catch(function () { return Promise.reject(new Error('JYBridge重连失败')); });
424
371
  }
425
- // Bridge完全不存在,执行初始化
372
+ // Bridge不存在,执行初始化
426
373
  if (this.initPromise) {
427
374
  return Promise.race([
428
375
  this.initPromise,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crh-jssdk",
3
- "version": "1.0.31",
3
+ "version": "1.0.32",
4
4
  "description": "crh-jssdk",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {