当前位置: 首页 > wzjs >正文

网站被劫持投稿网站

网站被劫持,投稿网站,天津网站搜索引擎优化,手表网站app推荐移动端APP与H5交互底层逻辑手机原生APP与WebView内部H5交互底层原理说明**一、交互底层原理****二、H5调用原生APP的实现方式****1. URL Scheme拦截****2. JavaScript接口注入****3. WebViewJavascriptBridge(iOS推荐)****三、原生APP调用H5的实现方式**…

移动端APP与H5交互底层逻辑

    • 手机原生APP与WebView内部H5交互底层原理说明
      • **一、交互底层原理**
      • **二、H5调用原生APP的实现方式**
        • **1. URL Scheme拦截**
        • **2. JavaScript接口注入**
        • **3. WebViewJavascriptBridge(iOS推荐)**
      • **三、原生APP调用H5的实现方式**
          • **1. 直接执行JavaScript代码**
        • **2. 事件监听机制**
      • **四、交互场景与工具推荐**
      • **五、安全优化建议**
    • **URL Scheme 拦截的详细实现**
      • **一、URL Scheme 拦截的原理**
      • **二、具体实现代码**
        • **1. H5 端代码**
        • **2. 原生端实现**
          • **(1)iOS(WKWebView + Swift)**
          • **(2)Android(WebView + Kotlin)**
      • **三、关键细节与优化**
        • **1. 参数解析**
        • **2. 回调机制**
        • **3. 性能优化**
        • **4. 安全性**
      • **四、优缺点分析**
      • **五、适用场景**
      • **总结**
    • JSBridge 原理详解
      • **一、核心机制:双向通信的 RPC 模型**
      • **二、底层实现方式**
        • **1. JavaScript 调用 Native 的两种主流方案**
        • **2. Native 调用 JavaScript 的两种方式**
      • **三、应用场景与优势**
        • **1. 核心应用场景**
        • **2. 优势对比**
      • **四、安全优化建议**

手机原生APP与WebView内部H5交互底层原理说明

一、交互底层原理

手机原生APP与WebView内部H5的交互本质是跨语言通信,通过WebView组件作为中介,实现原生代码(iOS的Swift/Objective-C、Android的Java/Kotlin)与Web内容(HTML/CSS/JavaScript)的双向通信。其核心机制如下:

  1. 双向通信层

    • H5调用原生:H5通过特定接口(如URL Scheme、JavaScript接口)触发原生代码执行。
    • 原生调用H5:原生通过WebView的API(如evaluateJavaScript)直接执行H5中的JavaScript函数。
  2. 关键角色

    • WebView组件:iOS的WKWebView/UIWebView,Android的WebView,作为H5的容器。
    • JSBridge:一套约定协议,封装通信细节,提供统一的API供双方调用。

二、H5调用原生APP的实现方式

1. URL Scheme拦截
  • 原理:H5通过导航到特定URL(如myapp://function?param=value)触发原生逻辑,原生通过拦截URL解析参数并执行操作。
  • 适用场景:简单功能调用(如跳转原生页面、分享)。
  • 样例
    // H5代码:触发原生分享
    function shareToNative() {window.location.href = 'myapp://share?title=Hello&content=World';
    }
    
    // iOS原生拦截(Swift)
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {if let url = navigationAction.request.url, url.scheme == "myapp" {if url.host == "share" {let params = parseQuery(url.query) // 解析参数shareContent(title: params["title"]!, content: params["content"]!)}decisionHandler(.cancel) // 阻止H5跳转} else {decisionHandler(.allow)}
    }
    
2. JavaScript接口注入
  • 原理:原生通过WebView注入JavaScript对象,H5直接调用该对象的方法。
  • 适用场景:复杂功能调用(如相机、定位)。
  • 样例
    // Android原生注入(Kotlin)
    class NativeBridge {@JavascriptInterfacefun openCamera() {// 调用原生相机}
    }val webView = findViewById<WebView>(R.id.web_view)
    webView.settings.javaScriptEnabled = true
    webView.addJavascriptInterface(NativeBridge(), "NativeApp") // 注入对象名为"NativeApp"
    
    // H5代码:调用原生相机
    function callNativeCamera() {if (window.NativeApp) {NativeApp.openCamera(); // 直接调用注入对象的方法}
    }
    
3. WebViewJavascriptBridge(iOS推荐)
  • 原理:通过第三方库(如WebViewJavascriptBridge)简化通信流程,支持同步/异步调用。
  • 样例
    // iOS原生注册处理器(Swift)
    import WebViewJavascriptBridgelet bridge = WKWebViewJavascriptBridge(for: webView)
    bridge.registerHandler("openCamera") { data, responseCallback inself.openCamera() // 调用原生相机responseCallback?("Camera opened") // 返回结果给H5
    }
    
    // H5代码:调用原生相机
    function callNativeCamera() {if (window.WebViewJavascriptBridge) {window.WebViewJavascriptBridge.callHandler('openCamera', {}, function(response) { console.log(response); } // 接收原生返回结果);}
    }
    

三、原生APP调用H5的实现方式

1. 直接执行JavaScript代码
  • 原理:原生通过WebView的API直接执行H5中的JavaScript函数。
  • 样例
    // Android原生调用H5方法(Kotlin)
    webView.evaluateJavascript("updateTitle('数据从原生传来')") { result ->Log.d("H5返回结果", result ?: "")
    }
    
    // iOS原生调用H5方法(Swift)
    webView.evaluateJavaScript("updateTitle('数据从原生传来')") { (result, error) inif let error = error {print("调用失败: \(error)")} else {print("H5返回结果: \(result ?? "")")}
    }
    
    // H5代码:定义供原生调用的方法
    window.updateTitle = function(info) {document.title = info; // 更新页面标题return "H5处理完成"; // 可选返回值
    };
    
2. 事件监听机制
  • 原理:原生触发H5中定义的事件,JavaScript通过监听事件响应。
  • 样例
    // H5代码:监听原生事件
    window.addEventListener('nativeEvent', function(e) {console.log('原生传来数据:', e.detail); // e.detail为原生传递的参数
    });
    
    // Android原生触发事件(Kotlin)
    webView.evaluateJavascript("""var event = new CustomEvent('nativeEvent', { detail: '数据从原生传来' });window.dispatchEvent(event);
    """) { }
    

四、交互场景与工具推荐

场景推荐方式工具/库
简单功能调用URL Scheme拦截
复杂功能调用JavaScript接口注入Android @JavascriptInterface
双向通信WebViewJavascriptBridgeiOS WebViewJavascriptBridge
高性能需求第三方桥接库DSBridge、Capacitor

五、安全优化建议

  1. 参数校验:对H5传入的参数进行合法性检查,防止注入攻击。
  2. 接口隔离:仅暴露必要方法,避免敏感API暴露。
  3. HTTPS加密:确保通信数据通过HTTPS传输,防止中间人攻击。
  4. 版本控制:通过JSBridge版本管理兼容性问题。

URL Scheme 拦截的详细实现

URL Scheme 拦截是 JSBridge 中最基础的通信方式之一,其核心原理是:WebView 通过拦截特定的 URL 请求,解析其中的协议、主机和参数,执行对应的原生逻辑。以下是具体实现步骤和代码示例。

一、URL Scheme 拦截的原理

  1. H5 触发通信

    • 通过修改 window.location.href 或动态创建 <iframe> 发起一个伪 URL 请求(如 myapp://openCamera?param=value)。
    • 原生侧拦截该请求,解析 URL 中的 schemehostquery 等信息,执行对应逻辑。
  2. 原生拦截并处理

    • iOS(WKWebView):通过 WKNavigationDelegatedecidePolicyFor 方法拦截。
    • Android(WebView):通过 WebViewClientshouldOverrideUrlLoading 方法拦截。
  3. 返回结果给 H5

    • 原生处理完成后,可通过 URL 回调直接执行 JS 返回结果。

二、具体实现代码

1. H5 端代码
// 定义通用的 JSBridge 调用方法
function callNative(action, params, callback) {const callbackId = 'cb_' + Date.now() + '_' + Math.random().toString(16).substr(2);window[callbackId] = callback; // 存储回调函数// 构造 URL Schemeconst query = Object.keys(params).map(key => `${key}=${encodeURIComponent(params[key])}`).join('&');const url = `myapp://${action}?${query}&callbackId=${callbackId}`;// 通过 iframe 触发(避免页面跳转)const iframe = document.createElement('iframe');iframe.style.display = 'none';iframe.src = url;document.body.appendChild(iframe);setTimeout(() => document.body.removeChild(iframe), 100);
}// 示例:调用原生相机
callNative('openCamera', { quality: 'high' }, (result) => {console.log('原生返回结果:', result);
});
2. 原生端实现
(1)iOS(WKWebView + Swift)
import WebKitclass ViewController: UIViewController, WKNavigationDelegate {var webView: WKWebView!override func viewDidLoad() {super.viewDidLoad()let config = WKWebViewConfiguration()webView = WKWebView(frame: .zero, configuration: config)webView.navigationDelegate = selfview.addSubview(webView)// 加载 H5 页面webView.load(URLRequest(url: URL(string: "https://example.com")!))}// 拦截 URL 请求func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {guard let url = navigationAction.request.url else {decisionHandler(.allow)return}// 检查是否为自定义 Schemeif url.scheme == "myapp" {handleNativeCall(url: url)decisionHandler(.cancel) // 阻止实际跳转} else {decisionHandler(.allow)}}// 处理原生调用private func handleNativeCall(url: URL) {guard let host = url.host, let query = url.query else { return }// 解析参数var params = [String: String]()let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItemsqueryItems?.forEach { params[$0.name] = $0.value }// 根据 host 执行不同逻辑switch host {case "openCamera":openCamera { imagePath in// 返回结果给 H5(通过 URL 回调)if let callbackId = params["callbackId"], let jsCallback = params["callbackId"] {let result = ["imagePath": imagePath]let json = try! JSONEncoder().encode(result)let js = "window.\(jsCallback)({success: true, data: \(String(data: json, encoding: .utf8)!)})"webView.evaluateJavaScript(js, completionHandler: nil)}}default:break}}// 示例:调用原生相机private func openCamera(completion: @escaping (String) -> Void) {// 实际调用相机逻辑(此处简化)DispatchQueue.main.asyncAfter(deadline: .now() + 1) {completion("/path/to/photo.jpg")}}
}
(2)Android(WebView + Kotlin)
class MainActivity : AppCompatActivity() {private lateinit var webView: WebViewoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)webView = findViewById(R.id.web_view)webView.settings.javaScriptEnabled = truewebView.webViewClient = MyWebViewClient()webView.loadUrl("https://example.com")}// 自定义 WebViewClient 拦截 URLprivate inner class MyWebViewClient : WebViewClient() {override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {val url = request?.url ?: return falseif (url.scheme == "myapp") {handleNativeCall(url)return true // 拦截请求}return false}}// 处理原生调用private fun handleNativeCall(url: Uri) {val host = url.hostval params = mutableMapOf<String, String>()url.queryParameterNames.forEach {params[it] = url.getQueryParameter(it) ?: ""}when (host) {"openCamera" -> {openCamera { imagePath ->// 返回结果给 H5(通过 URL 回调)val callbackId = params["callbackId"]val js = "window.${callbackId}({success: true, data: '$imagePath'})"webView.post { webView.evaluateJavascript(js, null) }}}}}// 示例:调用原生相机private fun openCamera(callback: (String) -> Unit) {// 实际调用相机逻辑(此处简化)Handler(Looper.getMainLooper()).postDelayed({callback("/path/to/photo.jpg")}, 1000)}
}

三、关键细节与优化

1. 参数解析
  • URL 编码:H5 需对参数进行 encodeURIComponent,避免特殊字符(如 &, =)破坏 URL 结构。
  • JSON 序列化:复杂数据(如对象、数组)应转为 JSON 字符串传递。
2. 回调机制
  • 全局回调存储:H5 将回调函数挂载到 window 对象(如 window.cb_123),原生执行 JS 时调用。
  • 避免内存泄漏:原生返回结果后,H5 应删除回调函数:
    function callNative(action, params, callback) {const callbackId = 'cb_' + Date.now();window[callbackId] = (result) => {callback(result);delete window[callbackId]; // 清理回调};// ...触发原生调用
    }
    
3. 性能优化
  • 使用 <iframe> 而非 location.href:避免页面跳转和历史记录污染。
  • 防重复拦截:对同一 URL 的多次拦截需去重(如 setTimeout 移除 iframe)。
4. 安全性
  • Scheme 白名单:仅允许特定 Scheme(如 myapp://),防止恶意链接。
  • 参数校验:原生需验证参数合法性(如文件路径是否在沙盒内)。

四、优缺点分析

优点缺点
实现简单,兼容性好参数长度受限(URL 限制)
无需注入对象,跨平台一致需手动解析 URL,易出错
适合简单功能调用性能较差(频繁 URL 解析)

五、适用场景

  • 简单功能:如分享、跳转原生页面、获取设备信息。
  • 兼容性要求高:需要支持旧版 WebView 或低版本 iOS/Android。
  • 快速原型开发:无需复杂封装,直接通过 URL 通信。

总结

URL Scheme 拦截是一种轻量级但灵活的 JSBridge 实现方式,适合简单交互场景。但对于复杂需求(如高频调用、大数据传输),建议使用 JavaScript 接口注入第三方库(如 WebViewJavascriptBridge)

JSBridge 原理详解

一、核心机制:双向通信的 RPC 模型

JSBridge 的本质是构建 JavaScript(Web)与原生代码(Native)之间的 RPC(远程过程调用)通道。由于两者运行在隔离的上下文(WebView 的 JavaScript 引擎 vs 原生运行时),通信需通过中介层实现,其核心逻辑可拆解为:

  1. 通信协议设计

    • 消息格式:通常采用 JSON 结构化数据,例如:
      {"action": "openCamera", "params": {"quality": "high"}, "callbackId": "cb_123"
      }
      
    • 回调机制:通过唯一 callbackId 实现异步响应,例如:
      {"callbackId": "cb_123", "success": true, "data": {"imagePath": "/path/to/photo.jpg"}
      }
      
  2. 角色分工

    • Web 端:发起调用(Client),处理原生返回结果。
    • Native 端:接收请求(Server),执行功能并返回结果。

二、底层实现方式

1. JavaScript 调用 Native 的两种主流方案
  • 方案一:注入 API(推荐)

    • 原理:原生通过 WebView 接口向 JavaScript 环境注入对象或方法,Web 直接调用。

    • Android 示例

      // 定义原生接口类
      class NativeBridge {@JavascriptInterfacepublic void openCamera(String callbackId) {// 调用相机逻辑String imagePath = takePhoto();// 返回结果给 WebwebView.evaluateJavascript("JSBridge.receiveNativeCallback('$callbackId', true, '$imagePath')", null);}
      }
      // 注入接口到 WebView
      webView.addJavascriptInterface(new NativeBridge(), "NativeApp");
      
      // Web 调用原生相机
      function callNativeCamera() {window.NativeApp.openCamera("cb_123");
      }
      
    • iOS 示例(WKWebView)

      // 注册消息处理器
      let contentController = WKUserContentController()
      contentController.add(self, name: "nativeHandler")
      let config = WKWebViewConfiguration()
      config.userContentController = contentController
      let webView = WKWebView(frame: .zero, configuration: config)// 处理 Web 调用
      extension ViewController: WKScriptMessageHandler {func userContentController(_ controller: WKUserContentController, didReceive message: WKScriptMessage) {if message.name == "nativeHandler" {let body = message.body as? [String: Any]let action = body?["action"] as? Stringif action == "openCamera" {openCamera { imagePath inlet callbackScript = """JSBridge.receiveNativeCallback('\(body?["callbackId"] as? String ?? "")', true, '\(imagePath)')"""webView.evaluateJavaScript(callbackScript, completionHandler: nil)}}}}
      }
      
  • 方案二:拦截 URL Scheme

    • 原理:Web 通过修改 window.location.href 或创建 <iframe> 触发特定 URL,原生拦截并解析。
    • 示例
      // Web 触发原生分享
      function shareToNative() {const iframe = document.createElement('iframe');iframe.style.display = 'none';iframe.src = 'myapp://share?title=Hello&content=World';document.body.appendChild(iframe);setTimeout(() => document.body.removeChild(iframe), 100);
      }
      
      // iOS 拦截 URL
      func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {if let url = navigationAction.request.url, url.scheme == "myapp" {if url.host == "share" {let params = parseQuery(url.query)shareContent(title: params["title"]!, content: params["content"]!)}decisionHandler(.cancel)} else {decisionHandler(.allow)}
      }
      
2. Native 调用 JavaScript 的两种方式
  • 直接执行 JS 代码

    // Android
    webView.evaluateJavascript("updateTitle('数据从原生传来')", null);
    
    // iOS
    webView.evaluateJavaScript("updateTitle('数据从原生传来')") { (result, error) inprint("H5返回结果: \(result ?? "")")
    }
    
  • 事件监听机制

    // Web 监听原生事件
    window.addEventListener('nativeEvent', function(e) {console.log('原生传来数据:', e.detail);
    });
    
    // Android 触发事件
    webView.evaluateJavascript("""var event = new CustomEvent('nativeEvent', { detail: '数据从原生传来' });window.dispatchEvent(event);
    """) { }
    

三、应用场景与优势

1. 核心应用场景
  • 原生功能调用

    • 摄像头、相册、定位、支付、二维码扫描等硬件操作。
    • 示例:Web 调用原生相机拍照后上传。
  • 动态内容更新

    • 通过 Web 动态下发活动页面、广告素材,原生提供底层能力支持。
    • 示例:电商 App 的促销活动页(H5)调用原生分享功能。
  • 跨平台开发

    • 在 React Native、Flutter 等框架中,JSBridge 实现 Web 与原生组件的混合渲染。
    • 示例:React Native 的 WebView 组件通过 JSBridge 与原生通信。
  • 性能优化

    • 将复杂计算或高频交互逻辑(如动画、列表渲染)放在原生侧,Web 通过 JSBridge 触发。
2. 优势对比
方案优点缺点
注入 API类型安全、支持复杂参数、性能高需处理不同平台兼容性(iOS/Android)
URL Scheme实现简单、跨平台一致参数长度受限、需手动解析 URL
第三方库功能全面(如 DSBridge 支持同步调用)增加包体积、学习成本

四、安全优化建议

  1. 参数校验

    • 对 Web 传入的参数进行合法性检查,防止 SQL 注入或路径遍历攻击。
    • 示例:校验图片路径是否在应用沙盒内。
  2. 接口隔离

    • 仅暴露必要方法,避免敏感 API(如文件系统访问)暴露给 Web。
    • 示例:通过白名单控制可调用的原生方法。
  3. HTTPS 加密

    • 确保通信数据通过 HTTPS 传输,防止中间人攻击。
  4. 版本控制

    • 通过 JSBridge 版本号管理兼容性问题,避免因接口变更导致崩溃。
    • 示例:Web 调用前检查原生是否支持当前接口版本。
http://www.dtcms.com/wzjs/162126.html

相关文章:

  • 金坛网站优化google官方入口
  • 凡科网免费做网站域名邮箱 400电话
  • 建网站的重要性百度网站流量查询
  • 百度如何网站推广方案设计
  • 做网站收费 优帮云安卓手机游戏优化器
  • 简述网站的建设步骤申请一个网站
  • 怎样建设卡盟网站关键词seo排名怎么选
  • 影视视频网站怎么做seo是什么服
  • 网站建设维护的职位上海百度关键词优化公司
  • 合肥动态网站制作建设免费发布推广信息网站
  • 行业类网站模板关键词优化武汉
  • 做下载网站赚钱吗ui培训
  • 网站建设典型材料seo刷排名工具
  • JAVA网站开发部署google adwords关键词工具
  • 企业电子商务网站建设评估试验免费seo推广计划
  • 哪些网站是用twcms做的5g网络优化工程师
  • 国外做外汇网站交流网站建设在线建站
  • 建设部网站录入业绩网络营销活动策划方案模板
  • 网上做任务网站有哪些内容宁波网站排名优化seo
  • 网站建设培训东莞小企业广告投放平台
  • 建设路小学网站2023年国际新闻大事件10条
  • 动漫网站的设计与实现超级优化大师下载
  • 网站建设要学哪些方面东莞整站优化
  • wordpress十佳主题北京seo服务商
  • html网站两边的浮窗怎么做网站网络推广运营
  • 上海黄浦 网站建设搜狐财经峰会直播
  • 巴市建网站网络推广和seo
  • 新建网站外链怎么做搜索指数查询平台
  • 网站页面优化公告网络运营需要学什么
  • 电子商务网站建设学什么软件推广app平台