@hd-front-end/jsbridge-sdk 1.0.4 → 1.0.6
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/dist/index.esm.js +167 -33
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +167 -33
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +167 -33
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -223,9 +223,20 @@ class Bridge {
|
|
|
223
223
|
const timeoutId = setTimeout(() => {
|
|
224
224
|
reject(new Error(`${method} 调用超时`));
|
|
225
225
|
}, 10000);
|
|
226
|
+
// 核心防御:防止 DataCloneError 和 Vue Proxy 序列化失败
|
|
227
|
+
// 剥离可能存在的不可序列化对象(如 success/fail 回调函数,或者 Vue 的 Proxy 对象)
|
|
228
|
+
let safeData = data;
|
|
229
|
+
if (data && typeof data === 'object') {
|
|
230
|
+
try {
|
|
231
|
+
safeData = JSON.parse(JSON.stringify(data));
|
|
232
|
+
}
|
|
233
|
+
catch (e) {
|
|
234
|
+
// 忽略异常,保留原数据
|
|
235
|
+
}
|
|
236
|
+
}
|
|
226
237
|
// Android 调用
|
|
227
238
|
if (this.platform === 'android' && this.bridge) {
|
|
228
|
-
this.bridge.callHandler(method,
|
|
239
|
+
this.bridge.callHandler(method, safeData, (result) => {
|
|
229
240
|
clearTimeout(timeoutId);
|
|
230
241
|
resolve(result);
|
|
231
242
|
});
|
|
@@ -247,17 +258,6 @@ class Bridge {
|
|
|
247
258
|
reject(err);
|
|
248
259
|
}
|
|
249
260
|
};
|
|
250
|
-
// 核心防御:防止 DataCloneError
|
|
251
|
-
// 剥离可能存在的不可序列化对象(如 success/fail 回调函数)
|
|
252
|
-
let safeData = data;
|
|
253
|
-
if (data && typeof data === 'object') {
|
|
254
|
-
try {
|
|
255
|
-
safeData = JSON.parse(JSON.stringify(data));
|
|
256
|
-
}
|
|
257
|
-
catch (e) {
|
|
258
|
-
// 忽略异常,保留原数据
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
261
|
handler.postMessage({
|
|
262
262
|
handlerName: method,
|
|
263
263
|
data: safeData,
|
|
@@ -1339,6 +1339,140 @@ async function logout() {
|
|
|
1339
1339
|
}
|
|
1340
1340
|
}
|
|
1341
1341
|
|
|
1342
|
+
// @ts-nocheck
|
|
1343
|
+
class JsBridge {
|
|
1344
|
+
static setup() {
|
|
1345
|
+
if (this.isInitialized) {
|
|
1346
|
+
return Promise.resolve();
|
|
1347
|
+
}
|
|
1348
|
+
return new Promise((resolve, reject) => {
|
|
1349
|
+
// Android 原生环境:按原有逻辑初始化 WKWebViewJavascriptBridge
|
|
1350
|
+
if (JsBridge.isSoaAndroid) {
|
|
1351
|
+
if (window.WKWebViewJavascriptBridge) {
|
|
1352
|
+
JsBridge.bridge = window.WKWebViewJavascriptBridge;
|
|
1353
|
+
JsBridge.isInitialized = true;
|
|
1354
|
+
resolve();
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
window.WKWVJBCallbacks = [
|
|
1358
|
+
(bridge) => {
|
|
1359
|
+
JsBridge.bridge = bridge;
|
|
1360
|
+
JsBridge.isInitialized = true;
|
|
1361
|
+
resolve();
|
|
1362
|
+
}
|
|
1363
|
+
];
|
|
1364
|
+
if (!window.InjectJavascript) {
|
|
1365
|
+
reject(new Error('调用失败:InjectJavascript不存在,请检查Android端注入逻辑'));
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1368
|
+
window.InjectJavascript.init();
|
|
1369
|
+
return;
|
|
1370
|
+
}
|
|
1371
|
+
// iOS 原生环境:只要 JsBridge 通道存在即可认为初始化成功
|
|
1372
|
+
if (JsBridge.isIosApp()) {
|
|
1373
|
+
JsBridge.isInitialized = true;
|
|
1374
|
+
resolve();
|
|
1375
|
+
return;
|
|
1376
|
+
}
|
|
1377
|
+
// 其它环境:明确失败,方便 H5 判断
|
|
1378
|
+
reject(new Error('调用失败:当前不是 SoaAndroid 或 Soa iOS 环境'));
|
|
1379
|
+
});
|
|
1380
|
+
}
|
|
1381
|
+
static async registerHandler(method, handler) {
|
|
1382
|
+
if (!JsBridge.inAndroidApp() && !JsBridge.isIosApp())
|
|
1383
|
+
return;
|
|
1384
|
+
if (!JsBridge.isInitialized) {
|
|
1385
|
+
await JsBridge.setup();
|
|
1386
|
+
}
|
|
1387
|
+
if (JsBridge.inAndroidApp()) {
|
|
1388
|
+
JsBridge.bridge.registerHandler(method, handler);
|
|
1389
|
+
}
|
|
1390
|
+
else {
|
|
1391
|
+
// iOS 环境下,对接由 JSBridge.swift 注入的底层 bridge
|
|
1392
|
+
const w = window;
|
|
1393
|
+
if (w.WebViewJavascriptBridge) {
|
|
1394
|
+
w.WebViewJavascriptBridge.registerHandler(method, handler);
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
static _handleMessageFromNative(messageJSON) {
|
|
1399
|
+
const w = window;
|
|
1400
|
+
if (w.WebViewJavascriptBridge && w.WebViewJavascriptBridge._handleMessageFromNative) {
|
|
1401
|
+
w.WebViewJavascriptBridge._handleMessageFromNative(messageJSON);
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
static async callHandler(method, data = null) {
|
|
1405
|
+
// Android
|
|
1406
|
+
if (JsBridge.inAndroidApp()) {
|
|
1407
|
+
if (!JsBridge.isInitialized) {
|
|
1408
|
+
await JsBridge.setup();
|
|
1409
|
+
}
|
|
1410
|
+
return new Promise((resolve) => {
|
|
1411
|
+
JsBridge.bridge.callHandler(method, data, (result) => {
|
|
1412
|
+
resolve(result);
|
|
1413
|
+
});
|
|
1414
|
+
});
|
|
1415
|
+
}
|
|
1416
|
+
// iOS
|
|
1417
|
+
if (JsBridge.isIosApp()) {
|
|
1418
|
+
return new Promise((resolve, reject) => {
|
|
1419
|
+
const w = window;
|
|
1420
|
+
const handler = w.webkit && w.webkit.messageHandlers && w.webkit.messageHandlers.JsBridge;
|
|
1421
|
+
if (!handler || typeof handler.postMessage !== 'function') {
|
|
1422
|
+
reject(new Error('调用失败:iOS JsBridge handler 不存在'));
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
const callbackId = 'cb_' + JsBridge.seq++;
|
|
1426
|
+
JsBridge.callbacks[callbackId] = { resolve, reject };
|
|
1427
|
+
handler.postMessage({
|
|
1428
|
+
handlerName: method,
|
|
1429
|
+
data,
|
|
1430
|
+
callbackId
|
|
1431
|
+
});
|
|
1432
|
+
});
|
|
1433
|
+
}
|
|
1434
|
+
return Promise.reject(new Error('调用失败:当前环境不支持 JsBridge.callHandler'));
|
|
1435
|
+
}
|
|
1436
|
+
static _invokeCallback(callbackId, result, error) {
|
|
1437
|
+
const entry = JsBridge.callbacks[callbackId];
|
|
1438
|
+
if (!entry)
|
|
1439
|
+
return;
|
|
1440
|
+
delete JsBridge.callbacks[callbackId];
|
|
1441
|
+
if (error) {
|
|
1442
|
+
entry.reject(error);
|
|
1443
|
+
}
|
|
1444
|
+
else {
|
|
1445
|
+
entry.resolve(result);
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
static isReady() {
|
|
1449
|
+
return JsBridge.isInitialized;
|
|
1450
|
+
}
|
|
1451
|
+
static inAndroidApp() {
|
|
1452
|
+
return JsBridge.isSoaAndroid;
|
|
1453
|
+
}
|
|
1454
|
+
static isIosApp() {
|
|
1455
|
+
if (typeof window === 'undefined')
|
|
1456
|
+
return false;
|
|
1457
|
+
const w = window;
|
|
1458
|
+
return !!(w.webkit && w.webkit.messageHandlers && w.webkit.messageHandlers.JsBridge);
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
JsBridge.bridge = null;
|
|
1462
|
+
JsBridge.isInitialized = false;
|
|
1463
|
+
// #ifndef H5
|
|
1464
|
+
JsBridge.isSoaAndroid = false;
|
|
1465
|
+
// #endif
|
|
1466
|
+
// #ifdef H5
|
|
1467
|
+
JsBridge.isSoaAndroid = Boolean(navigator.userAgent.match(/SoaAndroid/gi));
|
|
1468
|
+
// #endif
|
|
1469
|
+
JsBridge.callbacks = {};
|
|
1470
|
+
JsBridge.seq = 1;
|
|
1471
|
+
// 关键:把 JsBridge 挂到 window 上,给原生回调用
|
|
1472
|
+
if (typeof window !== 'undefined') {
|
|
1473
|
+
window.JsBridge = JsBridge;
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1342
1476
|
class PageLifeCycle {
|
|
1343
1477
|
constructor(state, route) {
|
|
1344
1478
|
this.state = state;
|
|
@@ -1369,54 +1503,54 @@ class JsBridgeHandlers {
|
|
|
1369
1503
|
* @param from
|
|
1370
1504
|
*/
|
|
1371
1505
|
static handleRouterAfterEach(to, from) {
|
|
1372
|
-
return
|
|
1506
|
+
return JsBridge.callHandler('routerAfterEach', { to, from });
|
|
1373
1507
|
}
|
|
1374
1508
|
/**
|
|
1375
1509
|
* 获取app端信息
|
|
1376
1510
|
*/
|
|
1377
1511
|
static handleGetAppInfo() {
|
|
1378
|
-
return
|
|
1512
|
+
return JsBridge.callHandler('getAppInfo');
|
|
1379
1513
|
}
|
|
1380
1514
|
/**
|
|
1381
1515
|
* 页面生命周期通知原生
|
|
1382
1516
|
* @param lifecycle
|
|
1383
1517
|
*/
|
|
1384
1518
|
static handlePageLifeCycle(lifecycle) {
|
|
1385
|
-
return
|
|
1519
|
+
return JsBridge.callHandler('uniPageLifeCycle', lifecycle);
|
|
1386
1520
|
}
|
|
1387
1521
|
/**
|
|
1388
1522
|
* 注册路由跳转调用
|
|
1389
1523
|
* @param handler
|
|
1390
1524
|
*/
|
|
1391
1525
|
static registerOnRoute(handler) {
|
|
1392
|
-
return
|
|
1526
|
+
return JsBridge.registerHandler('route', handler);
|
|
1393
1527
|
}
|
|
1394
1528
|
/**
|
|
1395
1529
|
* 注册获取路由信息调用
|
|
1396
1530
|
*/
|
|
1397
1531
|
static registerOnGetRouteInfo(handler) {
|
|
1398
|
-
return
|
|
1532
|
+
return JsBridge.registerHandler('getRouteInfo', handler);
|
|
1399
1533
|
}
|
|
1400
1534
|
/**
|
|
1401
1535
|
* 注册刷新store数据
|
|
1402
1536
|
* @param handler
|
|
1403
1537
|
*/
|
|
1404
1538
|
static registerOnRefreshStore(handler) {
|
|
1405
|
-
return
|
|
1539
|
+
return JsBridge.registerHandler('refreshStore', handler);
|
|
1406
1540
|
}
|
|
1407
1541
|
/**
|
|
1408
1542
|
* 注册PDA扫码回调
|
|
1409
1543
|
* @param handler
|
|
1410
1544
|
*/
|
|
1411
1545
|
static registerOnPdaScan(handler) {
|
|
1412
|
-
return
|
|
1546
|
+
return JsBridge.registerHandler('pdaScan', handler);
|
|
1413
1547
|
}
|
|
1414
1548
|
/**
|
|
1415
1549
|
* 调用原生扫码
|
|
1416
1550
|
* @param request
|
|
1417
1551
|
*/
|
|
1418
1552
|
static handleScan(request = new UniScanRequest()) {
|
|
1419
|
-
return
|
|
1553
|
+
return JsBridge.callHandler('scan', request).then((res) => {
|
|
1420
1554
|
const json = JSON.parse(res);
|
|
1421
1555
|
const result = new UniScanResult();
|
|
1422
1556
|
// eslint-disable-next-line @typescript-eslint/camelcase
|
|
@@ -1433,7 +1567,7 @@ class JsBridgeHandlers {
|
|
|
1433
1567
|
* @param request
|
|
1434
1568
|
*/
|
|
1435
1569
|
static handleChooseMedia(request) {
|
|
1436
|
-
return
|
|
1570
|
+
return JsBridge.callHandler('chooseMedia', request).then((res) => {
|
|
1437
1571
|
if (res) {
|
|
1438
1572
|
const result = JSON.parse(res);
|
|
1439
1573
|
return result;
|
|
@@ -1447,7 +1581,7 @@ class JsBridgeHandlers {
|
|
|
1447
1581
|
* @param request
|
|
1448
1582
|
*/
|
|
1449
1583
|
static handleGetImageInfo(request) {
|
|
1450
|
-
return
|
|
1584
|
+
return JsBridge.callHandler('getImageInfo', request).then((res) => {
|
|
1451
1585
|
const result = JSON.parse(res);
|
|
1452
1586
|
return result;
|
|
1453
1587
|
});
|
|
@@ -1457,7 +1591,7 @@ class JsBridgeHandlers {
|
|
|
1457
1591
|
* @param request
|
|
1458
1592
|
*/
|
|
1459
1593
|
static handleUploadFile(request) {
|
|
1460
|
-
return
|
|
1594
|
+
return JsBridge.callHandler('uploadFile', request).then((res) => {
|
|
1461
1595
|
const result = JSON.parse(res);
|
|
1462
1596
|
return result;
|
|
1463
1597
|
});
|
|
@@ -1467,28 +1601,28 @@ class JsBridgeHandlers {
|
|
|
1467
1601
|
* @param request
|
|
1468
1602
|
*/
|
|
1469
1603
|
static handleCloseWebView() {
|
|
1470
|
-
return
|
|
1604
|
+
return JsBridge.callHandler('closeWebView');
|
|
1471
1605
|
}
|
|
1472
1606
|
/**
|
|
1473
1607
|
* 打电话
|
|
1474
1608
|
* @param request
|
|
1475
1609
|
*/
|
|
1476
1610
|
static handleMakePhoneCall(request) {
|
|
1477
|
-
return
|
|
1611
|
+
return JsBridge.callHandler('makePhoneCall', request);
|
|
1478
1612
|
}
|
|
1479
1613
|
/**
|
|
1480
1614
|
* 动态设置标题
|
|
1481
1615
|
* @param request
|
|
1482
1616
|
*/
|
|
1483
1617
|
static handleSetNavigationBar(request) {
|
|
1484
|
-
return
|
|
1618
|
+
return JsBridge.callHandler('setNavigationBar', request);
|
|
1485
1619
|
}
|
|
1486
1620
|
/**
|
|
1487
1621
|
* 打日志
|
|
1488
1622
|
* @param request
|
|
1489
1623
|
*/
|
|
1490
1624
|
static handleLog(request) {
|
|
1491
|
-
return
|
|
1625
|
+
return JsBridge.callHandler('log', request);
|
|
1492
1626
|
}
|
|
1493
1627
|
/**
|
|
1494
1628
|
* 通知原生APP已加载完成
|
|
@@ -1502,28 +1636,28 @@ class JsBridgeHandlers {
|
|
|
1502
1636
|
* @param data
|
|
1503
1637
|
*/
|
|
1504
1638
|
static handleLogout() {
|
|
1505
|
-
return
|
|
1639
|
+
return JsBridge.callHandler('logout');
|
|
1506
1640
|
}
|
|
1507
1641
|
/**
|
|
1508
1642
|
* 通知原生APP打开链接
|
|
1509
1643
|
* @param data
|
|
1510
1644
|
*/
|
|
1511
1645
|
static handleOpenSchemeUrl(request) {
|
|
1512
|
-
return
|
|
1646
|
+
return JsBridge.callHandler('openSchemeUrl', request);
|
|
1513
1647
|
}
|
|
1514
1648
|
/**
|
|
1515
1649
|
* 图片路径转换成base64格式
|
|
1516
1650
|
* @param path
|
|
1517
1651
|
*/
|
|
1518
1652
|
static handlePathToBase64(request) {
|
|
1519
|
-
return
|
|
1653
|
+
return JsBridge.callHandler('pathToBase64', request).then((res) => {
|
|
1520
1654
|
const result = JSON.parse(res);
|
|
1521
1655
|
return result;
|
|
1522
1656
|
});
|
|
1523
1657
|
}
|
|
1524
1658
|
static handleBluetoothPrintImage(request) {
|
|
1525
1659
|
console.log(request);
|
|
1526
|
-
return
|
|
1660
|
+
return JsBridge.callHandler('printImage', request).then((res) => {
|
|
1527
1661
|
if (!res)
|
|
1528
1662
|
return res;
|
|
1529
1663
|
if (typeof res === 'string') {
|
|
@@ -1542,7 +1676,7 @@ class JsBridgeHandlers {
|
|
|
1542
1676
|
* @param data
|
|
1543
1677
|
*/
|
|
1544
1678
|
static handleBluetoothPrint(request) {
|
|
1545
|
-
return
|
|
1679
|
+
return JsBridge.callHandler('bluetoothPrint', request).then((res) => {
|
|
1546
1680
|
if (!res)
|
|
1547
1681
|
return res;
|
|
1548
1682
|
if (typeof res === 'string') {
|
|
@@ -1561,7 +1695,7 @@ class JsBridgeHandlers {
|
|
|
1561
1695
|
* @param request
|
|
1562
1696
|
*/
|
|
1563
1697
|
static handleReloadModule(request) {
|
|
1564
|
-
return
|
|
1698
|
+
return JsBridge.callHandler('reloadModule', request);
|
|
1565
1699
|
}
|
|
1566
1700
|
}
|
|
1567
1701
|
|