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