目次
1. window.external.notify
2. URL
ホームページ ウェブフロントエンド htmlチュートリアル 自分でカササギ ブリッジを構築する ネイティブ ページと Web View 間の JSBridge 実装_html/css_WEB-ITnose

自分でカササギ ブリッジを構築する ネイティブ ページと Web View 間の JSBridge 実装_html/css_WEB-ITnose

Jun 21, 2016 am 08:52 AM

JSBridge と言えば、皆さんが最もよく知っているのは WeChat の WeixinJSBridge です。これを介して、各パブリック ページはバックエンド メソッドを呼び出して WeChat と対話し、ユーザーに関連機能を提供できます。 UWP で独自の JSBridge を実装する方法について話しましょう。

win10 より前は、JSBridge を実装する必要がある場合、次の 2 つのメソッドがありました。

1. window.external.notify

WebView を使用したことのある人なら誰でもよく知っているはずです。 、HTML ページは window.external.notify を通じてメッセージを送信でき、クライアントは WebView.ScriptNotify イベントを使用してメッセージを受信しますが、双方は文字列を使用してのみ通信できるため、通常はメッセージ形式 (json など) を定義します。 。 UWP でこのメソッドを使用するには制限があります。つまり、サイトを .appxmanifest のコンテンツ URI に追加して、これらのドメイン名の JS スクリプトが windows.external.notify メソッドを呼び出せることをシステムに伝える必要があります。もちろんローカルjsであればそのような制限はありません。追加方法は以下の通りです。

しかし、私たちは常にいくつかの特別なニーズを抱えています。たとえば、WeChat/淘宝網アプリケーションはどうですか?ドメイン名はいつでも追加される可能性があるため、毎回マニフェストを更新してからストアを更新することはできません。 8.1 では、WebView.AllowedScriptNotifyUris を使用してアプリケーションに信頼できるサイトを動的に追加することもできますが、このインターフェイスは win10 では廃止されました。アプリケーションが信頼できるサイトを頻繁に/動的に変更する必要がない場合は、この方法を引き続き使用できます。

バックグラウンドで結果を処理した後、WebView.InvokeScript/InvokeScriptAsync メソッドを通じて現在のページの js メソッドを呼び出すことができます。

最初のパラメータは js メソッド名で、 2 番目のパラメータは、メソッドに必要なパラメータを呼び出します。

このメソッドは間違いを犯しやすいことに注意してください。例外のキャッチ:( に注意してください。生成される例外は基本的にいくつかの 0xXXXXX コードです。

 1     public sealed partial class MainPage : Page 2     { 3         BridgeObject.Bridge _bridge = new BridgeObject.Bridge(); 4  5         public MainPage() 6         { 7             this.InitializeComponent(); 8  9             this.wv.ScriptNotify += Wv_ScriptNotify;10 11             this.Loaded += MainPage_Loaded;12         }13 14         private async void Wv_ScriptNotify(object sender, NotifyEventArgs e)15         {16             await (new MessageDialog(e.Value)).ShowAsync();17 18             //返回结果给html页面19             await this.wv.InvokeScriptAsync("recieve", new[] { "hehe, 我是个结果"});20         }21 22         private void MainPage_Loaded(object sender, RoutedEventArgs e)23         {24             //我们事先写好了一个本地html页面用来做测试25             this.wv.Navigate(new Uri("ms-appx-web:///assets/html/index.html", UriKind.RelativeOrAbsolute));26         }27     }View Code
ログイン後にコピー

htmlコード:

 1 <!DOCTYPE html> 2  3 <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> 4 <head> 5     <meta charset="utf-8" /> 6     <title></title> 7  8     <script> 9 10         //通知后台11         function func1()12         {13     14                 window.external.notify("this is a message");15             16         }17 18         //这个方法用来接收后台的结果19         function recieve(value)20         {21             output.textContent = value;22         }23 24     </script>25 </head>26 <body>27     <div style="margin-top:100px">28         <button id="fun1Btn" onclick="func1();">Call method 1</button>29         <div id="output"></div>30     </div>31 </body>32 </html>View Code
ログイン後にコピー

2. URL

はい、正しくお読みいただけました。URL を使用して JSBridge を実装することもできます。これは、諦めた後の次のステップでもあります。以前の方法 代替プラン。タオバオには前述の問題があるため、サイトが修正されない可能性があり、アプリケーションを更新することは明らかに賢明な選択ではありません。具体的には、HTML ページがバックグラウンド コードを呼び出す必要があるたびに、ページ ジャンプが行われます。もちろん、ジャンプ URL は特定のルールに従っており、パラメーターを追加できます。その後、WebView.NavigationStarting イベントを使用してジャンプをインターセプトし、そのような一見実行可能なソリューションが登場しました。

コードは実際には非常に単純で、URL パラメーターを解析し、WebView.InvokeScript/InvokeScriptAsync メソッドを通じて結果をページに返します (このメソッドはサイトに固有のものではありません)。十分に動的で、十分シンプルであるように見えますが、実際に使用していると、WebView の URL には最大長の制限があることに突然気づきました。

 1         private void Wv_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args) 2         { 3             if(args.Uri.OriginalString.StartsWith("http://our/jsbridge/url/pattern")) 4             { 5                 //是一次jsbridge调用,取消本次跳转 6                 args.Cancel = true; 7  8                 //这里具体解析url的参数 9             }10         }View Code
ログイン後にコピー
は Android や IOS よりも小さいため、多くのパラメータが切り捨てられ、最終的にはあきらめなければならなかったとき、別の bulingbuling メソッドが登場しました。目の前: WebView.AddWebAllowedObject。このメソッドは win10 で新しく追加されたメソッドで、Windows ランタイム オブジェクトを JS 呼び出しに直接渡すことができます。

このメソッドの定義は次のとおりです。 🎜>public void AddWebAllowedObject(string name, object pObject )

name は、js のオブジェクトに対応するグローバル変数名です。このメソッドを通じて html ページに渡されたオブジェクトは、js の window オブジェクトにハングされます。 pObject は渡されるオブジェクトです。

まず、新しい Windows ランタイム コンポーネント プロジェクトを作成し、新しいクラス Bridge を追加して、このクラスの特徴を確認します。

すべては、AllowForWebAttribute 機能にあります。これを使用すると、オブジェクトを Web ビューに渡すことができます。ただし、AddWebAllowedObject メソッドを NavigationStarting で呼び出す必要があることが 1 つあります。 (言いません、私は長い間 DomLoaded イベントに苦労していました...)

さあ、この奇跡を目撃する時が来ました。js でこのオブジェクトを呼び出す方法を見てみましょう。 ? (私の貧弱な HTML コードは無視してください...)
 1     //这个attribute是必须的,有了他我们的对象才能传递给WebView 2     [AllowForWeb] 3     public sealed class Bridge 4     { 5         /// <summary> 6         /// 提示一条消息 7         /// </summary> 8         /// <param name="msg"></param> 9         public void showMessage(string msg)10         {11             new MessageDialog(msg).ShowAsync();12         }13 14 15     }View Code
ログイン後にコピー

コードは非常に簡単です。唯一説明する必要があるのは、js でメソッドを呼び出すとき、最初の文字はすべて小文字であるということです。バックグラウンドで定義した最初の文字が大文字の場合、もちろん、これも JS の使用習慣に従っている必要があります)、結果を見てみましょう。
 1     public sealed partial class MainPage : Page 2     { 3         BridgeObject.Bridge _bridge = new BridgeObject.Bridge(); 4  5         public MainPage() 6         { 7             this.InitializeComponent(); 8  9             this.wv.NavigationStarting += Wv_NavigationStarting;10 11             this.Loaded += MainPage_Loaded;12         }13 14         private void MainPage_Loaded(object sender, RoutedEventArgs e)15         {16             //我们事先写好了一个本地html页面用来做测试17             this.wv.Navigate(new Uri("ms-appx-web:///assets/html/index.html", UriKind.RelativeOrAbsolute));18         }19 20         private void Wv_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)21         {22             //OURBRIDGEOBJ这个是我们的对象插入到页面之后对象的变量名,这是一个全局变量,也就是window.OURBRIDGEOBJ23             this.wv.AddWebAllowedObject("OURBRIDGEOBJ", _bridge);24         }25     }View Code
ログイン後にコピー

 1 <!DOCTYPE html> 2  3 <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> 4 <head> 5     <meta charset="utf-8" /> 6     <title></title> 7  8     <script> 9 10         function func1() {11             // 首先判断我们对象是否正确插入12             if (window.OURBRIDGEOBJ) {13                 //调用的我们消息函数14                 window.OURBRIDGEOBJ.showMessage("呵呵呵,我是个message");15             }16         }17     </script>18 </head>19 <body>20     <div style="margin-top:100px">21         <button id="fun1Btn" onclick="func1();">Call method 1</button>22     </div>23 </body>24 </html>View Code
ログイン後にコピー
もちろん、この機能だけを持っていてもそれほど面白くはありません。結局のところ、それは以前からできていました。

続行する前に、win10 より前に jsbridge 経由でバックグラウンド コードを呼び出したい場合は、非同期操作を実装する方法を考えてください。

1) まず、js 呼び出しは WebView.InvokeScript から分離されているため、通常はバックグラウンド操作が完了した後、各 js 呼び出しに対して ID を生成する必要があります。 、InvokeScript メソッドを介して 結果を返すとき、呼び出し ID を返し、どの呼び出し結果をページに伝える必要があります

3)。その後、js はこの ID に基づいてコールバックし、前の操作を続行します。

但是现在我们可以抛弃那些繁琐的步骤了,我们的Windows Runtime Component支持异步(IAsyncAction/IAsyncOperation),而js又支持 Promise ,结合在一起,你懂的!

先给我们的类添加一个简单的异步方法。

 1     //这个attribute是必须的,有了他我们的对象才能传递给WebView 2     [AllowForWeb] 3     public sealed class Bridge 4     { 5         /// <summary> 6         /// 提示一条消息 7         /// </summary> 8         /// <param name="msg"></param> 9         public void showMessage(string msg)10         {11             new MessageDialog(msg).ShowAsync();12         }13 14         public Windows.Foundation.IAsyncOperation<int> giveMeAnObject(int num)15         {16             return Task.Run(async () =>17             {18                 //延迟3秒钟,模拟异步任务:)19                 await Task.Delay(3000);20 21                 return ++num;22             }).AsAsyncOperation();23         }24     }View Code
ログイン後にコピー

接下来我们在js端,用 promise.then 来等待结果。

 1 <!DOCTYPE html> 2  3 <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> 4 <head> 5     <meta charset="utf-8" /> 6     <title></title> 7  8     <script> 9 10         function func1() {11             // 首先判断我们对象是否正确插入12             if (window.OURBRIDGEOBJ) {13                 //调用的我们消息函数14                 window.OURBRIDGEOBJ.showMessage("呵呵呵,我是个message");15             }16         }17 18         function func2() {19             if (window.OURBRIDGEOBJ) {20 21                 //对于js来说winrt的异步操作都会对应到promise上22                 var result = window.OURBRIDGEOBJ.giveMeAnObject(12);23 24                 // 等待结果25                 result.then(function (nextNum) {26                     // nextNum就是IAsyncOperation<int>的真正返回值27                     output.textContent = nextNum;28                 });29 30             }31         }32     </script>33 </head>34 <body>35     <div style="margin-top:100px">36         <button id="fun1Btn" onclick="func1();">Call method 1</button>37         <button id="fun2Btn" onclick="func2();">Call method 2</button>38         <div id="output" />39     </div>40 </body>41 </html>View Code
ログイン後にコピー

运行起来,等待3秒之后,结果出来了!

最后如果你觉得写component限制太多的话(继承都不让用。。),可以使用接口定义方法,然后在类库中实现这些方法也是一个不错的方案,下面是一个比较简单的实现供参考。

我们的jsbridge接口,包含我们准备提供的方法。

1     /// <summary>2     /// 用来定义JSBridge中实现的方法3     /// </summary>4     public interface IBridgeMethods5     {6         IAsyncOperation<int> GiveMmeAnObject(int num);7         void ShowMessage(string message);8     }View Code
ログイン後にコピー

修改我们的Bridge类,所有的方法都通过上面的接口来提供。

 1    //这个attribute是必须的,有了他我们的对象才能传递给WebView 2     [AllowForWeb] 3     public sealed class Bridge 4     { 5         private IBridgeMethods _methods = null; 6  7  8         /// <summary> 9         /// 提示一条消息10         /// </summary>11         /// <param name="msg"></param>12         public void ShowMessage(string msg)13         {14             _methods?.ShowMessage(msg);15         }16 17         public IAsyncOperation<int> giveMeAnObject(int num)18         {19             return _methods?.GiveMmeAnObject(num);20         }21 22         /// <summary>23         /// 初始化个方法的实现24         /// </summary>25         /// <param name="obj"></param>26         public void Init(IBridgeMethods obj)27         {28             _methods = obj;29         }30     }View Code
ログイン後にコピー
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

&lt; Progress&gt;の目的は何ですか 要素? &lt; Progress&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:34 PM

この記事では、HTML&lt; Progress&gt;について説明します。要素、その目的、スタイリング、および&lt; meter&gt;との違い要素。主な焦点は、&lt; Progress&gt;を使用することです。タスクの完了と&lt; Meter&gt; statiの場合

&lt; datalist&gt;の目的は何ですか 要素? &lt; datalist&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:33 PM

この記事では、HTML&lt; Datalist&GT;について説明します。オートコンプリートの提案を提供し、ユーザーエクスペリエンスの改善、エラーの削減によりフォームを強化する要素。

&lt; meter&gt;の目的は何ですか 要素? &lt; meter&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:35 PM

この記事では、html&lt; meter&gt;について説明します。要素は、範囲内でスカラーまたは分数値を表示するために使用され、Web開発におけるその一般的なアプリケーション。それは差別化&lt; Meter&gt; &lt; Progress&gt;およびex

HTML5のクロスブラウザー互換性のベストプラクティスは何ですか? HTML5のクロスブラウザー互換性のベストプラクティスは何ですか? Mar 17, 2025 pm 12:20 PM

記事では、HTML5クロスブラウザーの互換性を確保するためのベストプラクティスについて説明し、機能検出、プログレッシブエンハンスメント、およびテスト方法に焦点を当てています。

HTML5&lt; time&gt;を使用するにはどうすればよいですか 日付と時刻を意味的に表す要素? HTML5&lt; time&gt;を使用するにはどうすればよいですか 日付と時刻を意味的に表す要素? Mar 12, 2025 pm 04:05 PM

この記事では、html5&lt; time&gt;について説明します。セマンティックデート/時刻表現の要素。 人間の読み取り可能なテキストとともに、マシンの読みやすさ(ISO 8601形式)のDateTime属性の重要性を強調し、Accessibilitを増やします

HTML5フォーム検証属性を使用してユーザー入力を検証するにはどうすればよいですか? HTML5フォーム検証属性を使用してユーザー入力を検証するにはどうすればよいですか? Mar 17, 2025 pm 12:27 PM

この記事では、ブラウザのユーザー入力を直接検証するために、必要、パターン、MIN、MAX、および長さの制限などのHTML5フォーム検証属性を使用して説明します。

ビューポートメタタグとは何ですか?レスポンシブデザインにとってなぜそれが重要なのですか? ビューポートメタタグとは何ですか?レスポンシブデザインにとってなぜそれが重要なのですか? Mar 20, 2025 pm 05:56 PM

この記事では、モバイルデバイスのレスポンシブWebデザインに不可欠なViewportメタタグについて説明します。適切な使用により、最適なコンテンツのスケーリングとユーザーの相互作用が保証され、誤用が設計とアクセシビリティの問題につながる可能性があることを説明しています。

&lt; iframe&gt;の目的は何ですか タグ?使用する際のセキュリティ上の考慮事項は何ですか? &lt; iframe&gt;の目的は何ですか タグ?使用する際のセキュリティ上の考慮事項は何ですか? Mar 20, 2025 pm 06:05 PM

この記事では、&lt; iframe&gt;外部コンテンツをWebページ、その一般的な用途、セキュリティリスク、およびオブジェクトタグやAPIなどの代替案に埋め込む際のタグの目的。

See all articles