delphi FMX.WebBrowser与H5交互JavaScript

delphi FMX.WebBrowser与H5交互JavaScriptdelphiFMX WebBrowser 与 H5 交互 JavaScript 一 原理 1 1 前提条件 主要是针对 MSWindows 下对 D10 4 以下的 TWebBrowser 的支持 不过 D10 4 已解决了这个前提 你所选用的 JS 库或 JS 代码本身是很好的兼容 IE10 及其以上国内大厂和国外优质站点 一般在写 Web 代码时 都考虑了 IE 的兼容性问题 国内小厂 大多数的做得不好只考虑省事 少写了很多代码 引以为戒 你在发布自己的 API 时 一定要考虑浏览器内核的兼容

目录

delphi FMX.WebBrowser与H5交互JavaScript

本文讨论在FMX下,delphi webbrowser与js交互:

一、原理

1.1、前提条件(主要是针对MSWindows下对D10.4以下的TWebBrowser的支持,不过D10.4已解决了这个前提)

1.2、Delphi FMX.WebBrowser.pas

1.2.1、直接放个TWebBrowser可视化控件来交互FMX界面

1.2.2、动态产生客制化的TCustomWebBrowser非可视化控件来交互FMX界面

1.2.3、以FMX服务的方式IFMXWBService来交互FMX界面

1.3、综上所述:

二、应用

2.1、腾讯开源H5图形图形处理库AlloyImage

2.2、……(2021-01-12)写累了,明儿继续……


 

delphi FMX.WebBrowser与H5交互JavaScript

本文讨论在FMX下,delphi webbrowser与js交互:

一、原理

1.1、前提条件(主要是针对MSWindows下对D10.4以下的TWebBrowser的支持,不过D10.4已解决了这个前提)

        你所选用的JS库或JS代码本身是很好的兼容IE10及其以上

        国内大厂和国外优质站点,一般在写Web代码时,都考虑了IE的兼容性问题。国内小厂,大多数的做得不好只考虑省事、少写了很多代码,引以为戒,你在发布自己的API时,一定要考虑浏览器内核的兼容性,不要学习国内这些小厂。

1.2、Delphi FMX.WebBrowser.pas

以下三种方式,一个目的,都是为了拿到接口ICustomBrowser :

1.2.1、直接放个TWebBrowser可视化控件来交互FMX界面

        LWebBrowser :TWebBrowser;

1.2.2、动态产生客制化的TCustomWebBrowser非可视化控件来交互FMX界面

        LWebBrowser :TCustomWebBrowser;

        LWebBrowser.Create(AOwner: TComponent); 

1.2.3、以FMX服务的方式IFMXWBService来交互FMX界面

1.2.3.1、这是FMX.WebBrowser.Android、FMX.WebBrowser.Cocoa及FMX.WebBrowser.Win分别为Android、IOS、MSWINDOWS下完美拿到TWebBrowser接口ICustomBrowser最好的方法

1.2.3.2、然后ICustomBrowser执行JS

        ICustomBrowser. EvaluateJavaScript(const JavaScript: string);   //:执行JS,但不回调执行的结果

1.2.3.4、ICustomBrowser执行JS并回调:

1.2.3.4.1、Android

在Android 4.4之后,WebView提供了一个新的2个执行JS的接口:

$(BDS)\source\rtl\android\ unit Androidapi.JNI.Webkit; [JavaSignature('android/webkit/WebView')] JWebView = interface(JAbsoluteLayout) ['{0001776D-86A0-43B3-A64C-C6FEA095AD91}'] procedure addJavascriptInterface(object_: JObject; name: JString); cdecl; procedure evaluateJavascript(script: JString; resultCallback: JValueCallback); cdecl; //...................以下为delphi FMX通过TAndroidWebBrowserService调用ICustomBrowser.EvaluateJavaScript(const JavaScript: string)的Android实现的内部方法: //procedure loadUrl(url: JString; additionalHttpHeaders: JMap); cdecl; overload; procedure loadUrl(url: JString); cdecl; overload; //................... 

《=========拿到JValueCallback :

$(BDS)\source\rtl\android\ unit Androidapi.JNI.Webkit; JValueCallbackClass = interface(IJavaClass) ['{5CE4D0B0-6C4F-43BD-B57F-A06401A5FB2F}'] end; [JavaSignature('android/webkit/ValueCallback')] JValueCallback = interface(IJavaInstance) ['{3B24779A-3678-4AD8-B421-A8A9C6F3E742}'] procedure onReceiveValue(value: JObject); cdecl; end; TJValueCallback = class(TJavaGenericImport 
   
     ) end; 
   

《=========拿到JWebView :

$(BDS)\source\rtl\android\ unit Androidapi.JNI.Webkit; JWebViewClass = interface(JAbsoluteLayoutClass) ['{57C30F7F-F8C7-4C19-859E-073DC4DA4250}'] {class} function _GetRENDERER_PRIORITY_BOUND: Integer; cdecl; {class} function _GetRENDERER_PRIORITY_IMPORTANT: Integer; cdecl; {class} function _GetRENDERER_PRIORITY_WAIVED: Integer; cdecl; {class} function _GetSCHEME_GEO: JString; cdecl; {class} function _GetSCHEME_MAILTO: JString; cdecl; {class} function _GetSCHEME_TEL: JString; cdecl; {class} function init(context: JContext): JWebView; cdecl; overload; //............. 

 

$(BDS)\source\rtl\android\ unit Androidapi.JNI.Embarcadero; JWebBrowserClass = interface(JWebViewClass) ['{C9D39057-C2B7-4264-8E58-52DE4CA5AE56}'] {class} function init(context: JContext): JWebBrowser; cdecl; end; [JavaSignature('com/embarcadero/firemonkey/webbrowser/WebBrowser')] JWebBrowser = interface(JWebView) ['{-EEA5-4130-BE15-F23BEB8ECA69}'] procedure SetWebViewListener(listener: JOnWebViewListener); cdecl; end; TJWebBrowser = class(TJavaGenericImport 
   
     ) end; JWebClientClass = interface(JWebViewClientClass) ['{424BCB34-24B0-4A4B-830B-D396C}'] {class} function init: JWebClient; cdecl; end; 
   

最新的D10.4对应的Android SDK,Delphi为我们实现的API接口的基础知识:

delphi的类及其接口 和JAVA的类及其接口

delphi导入java类的方法:

方法一、原生方法导入:

//这是1个用于较易声明Java的泛型对象工厂的通用类。在这个模型中,我们划分为两个接口:类方法接口(第1个参数)和实例方法接口(第2个参数)。这个类将此2个接口融合到该工厂类中,可以产生Java的实例对象,或提供代表单线程实例的Java类的参照:

$(BDS)\source\rtl\android\ unit Androidapi.JNIBridge; /// A generic class that we use to make the declaration of Java /// object factories easier. In our model, we split the class methods /// and instance methods into two interfaces. This class blends the /// two interfaces into one factory that can produce instances of Java /// objects, or provide a reference to a singleton instance representing /// the Java class. //这是1个用于较易声明Java的泛型对象工厂的通用类。在它的模型中,我们将参数划分为两个接口:类方法接口(第1个参数)和实例方法接口(第2个参数)。这个类将此2个接口融合到该工厂类中,可以产生Java的实例对象,或提供代表单线程实例的Java类的参照: TJavaGenericImport 
   
     = class 
   

方法二、用EMB的代理接口导入DefaultProxyInterfaceName = ‘com/embarcadero/rtl/ProxyInterface’;  :

$(BDS)\source\rtl\android\ unit Androidapi.JNIBridge; TJInterfacedObject = class(TInterfacedObject) procedure AfterConstruction; override; procedure BeforeDestruction; override; end; TJavaLocal = class abstract (TJInterfacedObject, ILocalObject, IJava) const DefaultProxyInterfaceName = 'com/embarcadero/rtl/ProxyInterface'; 

———–>通过以上原理和方法,Delphi第三方生态ScriptGate(是一个实现Delphi和JavaScript相互调用的库,10.4以下使用,D10.4.1请不要再使用有问题)已经为我们做好了封装,可直接拿来用(https://bitbucket.org/freeonterminate/scriptgate/src/master/)。

    //……………………….现在使用 ScriptGate 可轻易解决这个问题,ScriptGate  支持 Windows, macOS, Android, iOS,非常好用,强烈推荐

    //……………………….(详述:略),自己下载后看。SGWebClient.jar:Android下高勇老师直接引用了这个封装。调用方法示例:http://bbs.2ccc.com/topic.asp?topicid=

———–>通过以上原理和方法,(修改:爱吃猪头肉 & Flying Wang 2015-07-21)已经为我们修改好了补丁单元Delphi10.4Update0_FixedDelphiPas\FMX.WebBrowser.pas,

(1)、新增 跨平台属性 GetRealWebBrowserObject 获取各个平台下 原生的 浏览器对象:

    :注意:《WebView在使用setUserAgentString时的坑https://blog.csdn.net/mahongy/article/details/

    :您若尝试确认正确后,请这样使用:

uses Androidapi.JNI.Webkit;

var LJWebSettings :JWebSettings ;    L_UA :JString;

begin

    LJWebSettings := (WebBrowser1.GetRealWebBrowserObject as JWebBrowser).getSettings ;

    L_UA:= LJWebSettings.getUserAgentString;

    LJWebSettings.setUserAgentString (L_UA) ;

    //       //LJWebSettings.setUserAgentString( StringToJString( L_UA+’ ; 你追加的UserAgent的自定义部分的字符串’ ) );

end;

user-agent,可以用getUserAgentString()方法获取,在手机上打印出来的结果是:

Mozilla/5.0 (Linux; Android 8.1.0; NX606J Build/OPM1..026; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36

delphi FMX.WebBrowser与H5交互JavaScript

 

(2)、新增 重定向 Redirection 功能:

    // 请设置好 RedirectionKey,千万不要用 URL 上的一些关键字,也不要用特殊字符:

    可直接拿来用:

(* *) (*                            *) (*    修改:爱吃猪头肉 & Flying Wang 2015-07-21    *) (*        上面的版权声明请不要移除。       *) (*                            *) (*         禁止发布到城通网盘。        *) (*                            *) (* 仅支持 RAD10.4.0(10.4 Release 0),其他版本请自行修改 *) (*                            *) (* *) { IFMXWebBrowserService } ICustomBrowser = interface(IInterface) ['{A5BB2E8C-6D53-4FF3-BC38-F07BD}'] // ........................... // procedure EvaluateJavaScript(const JavaScript: string); //Fix By Flying Wang and 爱吃猪头肉: procedure EvaluateJavaScript(const JavaScript: string; DidEvaluateJavaScript: TWebBrowserDidEvaluateJavaScript = nil); //Fix or Add By 爱吃猪头肉: function GetRealWebBrowserObject: IUnknown; //Fix 重定向关键字,如果包含这个关键字 页面不刷新: //解析 重定向字符串: function GetRedirectionKey: string; procedure SetRedirectionKey(const Value:string); property RedirectionKey: string read GetRedirectionKey write SetRedirectionKey; // ........................... procedure LoadFromStrings(const Content: string; const BaseUrl: string); // ........................... 

 

1.2.3.4.2、、IOS

———–>通过以上原理和方法,(修改:爱吃猪头肉 & Flying Wang 2015-07-21)已经为我们修改好了补丁单元:Delphi10.4Update0_FixedDelphiPas\FMX.WebBrowser.pas,

FMX.WebBrowser.Cocoa.pas

===========》TCommonWebBrowserService===========》继承后将protected的可见性发布出来使用,即可:

(* *) (*                            *) (*    修改:爱吃猪头肉 & Flying Wang 2015-07-21    *) (*        上面的版权声明请不要移除。       *) (*                            *) (*         禁止发布到城通网盘。        *) (*                            *) (* 仅支持 RAD10.4.0(10.4 Release 0),其他版本请自行修改 *) (*                            *) (* *) { TCommonWebBrowserService } TCommonWebBrowserService = class(TInterfacedObject, ICustomBrowser) //Fix 重定向关键字 private FRedirectionKey: string; private //................................... protected //................................... procedure LoadFromStrings(const Content: string; const BaseUrl: string); // procedure EvaluateJavaScript(const JavaScript: string); //Fix By Flying Wang and 爱吃猪头肉 procedure EvaluateJavaScript(const JavaScript: string; DidEvaluateJavaScript: TWebBrowserDidEvaluateJavaScript = nil); //Fix or Add By 爱吃猪头肉 function GetRealWebBrowserObject: IUnknown; //Fix 重定向关键字,如果包含这个关键字 页面不刷新 //解析 重定向字符串 function GetRedirectionKey: string; procedure SetRedirectionKey(const Value:string); //................................... 

 

1.2.3.4.3、Linux

 

———–>通过以上原理和方法,(修改:爱吃猪头肉 & Flying Wang 2015-07-21)已经为我们修改好了补丁单元Delphi10.4Update0_FixedDelphiPas\FMX.WebBrowser.pas,

(1)、新增 跨平台属性 GetRealWebBrowserObject 获取各个平台下 原生的 浏览器对象:

(2)、新增 重定向 Redirection 功能:

    // 请设置好 RedirectionKey,千万不要用 URL 上的一些关键字,也不要用特殊字符:

    可直接拿来用:

delphi FMX.WebBrowser与H5交互JavaScript

{ TLinuxWebBrowserService } TLinuxWebBrowserService = class(TInterfacedObject, ICustomBrowser) //Fix 重定向关键字 private FRedirectionKey: string; //............................... // procedure EvaluateJavaScript(const JavaScript: string); //Fix By Flying Wang and 爱吃猪头肉 procedure EvaluateJavaScript(const JavaScript: string; DidEvaluateJavaScript: TWebBrowserDidEvaluateJavaScript = nil); //Fix or Add By 爱吃猪头肉 function GetRealWebBrowserObject: IUnknown; //Fix 重定向关键字,如果包含这个关键字 页面不刷新 //解析 重定向字符串 function GetRedirectionKey: string; procedure SetRedirectionKey(const Value:string); procedure LoadFromStrings(const Content: string; const BaseUrl: string); //procedure EvaluateJavaScript(const JavaScript: string); //............................... 

1.2.3.4.4、MSWindows

———–>通过以上原理和方法,(修改:爱吃猪头肉 & Flying Wang 2015-07-21)已经为我们修改好了补丁单元:Delphi10.4Update0_FixedDelphiPas\FMX.WebBrowser.pas,

FMX.WebBrowser.Win.pas===========》TWindowsWebBrowserService ===========》直接使用public方法,即可:

(* *) (*                            *) (*    修改:爱吃猪头肉 & Flying Wang 2015-07-21    *) (*        上面的版权声明请不要移除。       *) (*                            *) (*         禁止发布到城通网盘。        *) (*                            *) (* 仅支持 RAD10.4.0(10.4 Release 0),其他版本请自行修改 *) (*                            *) (* *) TWindowsWebBrowserService = class; TWinWBMediator = class(TInterfacedObject, ICustomBrowser) private FBrowser: TWindowsWebBrowserService; public constructor Create; destructor Destroy; override; function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; property WB: TWindowsWebBrowserService read FBrowser implements ICustomBrowser; end; TWindowsWebBrowserService = class(TOLEFrameworkDelegate, ICustomBrowser) //Fix 重定向 关键字 private FRedirectionKey: string; private //.................................... public //.................................... // procedure EvaluateJavaScript(const JavaScript: string); //Fix By Flying Wang and 爱吃猪头肉 procedure EvaluateJavaScript(const JavaScript: string; DidEvaluateJavaScript: TWebBrowserDidEvaluateJavaScript = nil); //Fix or Add By 爱吃猪头肉 function GetRealWebBrowserObject: IUnknown; //Fix 重定向关键字,如果包含这个关键字 页面不刷新 //解析 重定向字符串 function GetRedirectionKey: string; procedure SetRedirectionKey(const Value:string); //.................................... 

 

1.2.3.4、事件中处理页面内容的回调

在这些事件中处理页面内容的回调:

页面回调BaseUrl,拿到回调结果字符串Content

接口ICustomBrowser :

      procedure LoadFromStrings(const Content: string; const BaseUrl: string);

扩展的接口:

1.2.3.5、D10.4对TEdgeBrowser的支持及其新增TWebBrowser通过SelectedEngine 来选择使用老的 IE 核心还是新的 Edge 核心,完美支持在MSWINDOWS下H5的各种性能

详见本博客博文:

《RAD Studio 10.4.1的TEdgeBrowser与javascript交互-基于Chromium的Edge浏览器控件用法之二》https://blog.csdn.net/pulledup/article/details/

《RAD Studio 10.4.1新的基于Chromium的Microsoft Edge浏览器的TEdgeBrowser控件用法》https://blog.csdn.net/pulledup/article/details/

1.3、综上所述:

———–>通过以上原理和方法,(修改:爱吃猪头肉 & Flying Wang 2015-07-21)已经为我们修改好了补丁单元Delphi10.4Update0_FixedDelphiPas\FMX.WebBrowser.pas,

(1)、新增 跨平台属性 GetRealWebBrowserObject 获取各个平台下 原生的 浏览器对象:

    :注意:《WebView在使用setUserAgentString时的坑https://blog.csdn.net/mahongy/article/details/

    :您若尝试确认正确后,请这样使用:

uses Androidapi.JNI.Webkit;

var LJWebSettings :JWebSettings ;    L_UA :JString;

begin

    LJWebSettings := (WebBrowser1.GetRealWebBrowserObject as JWebBrowser).getSettings ;

    L_UA:= LJWebSettings.getUserAgentString;

    LJWebSettings.setUserAgentString (L_UA) ;

    //       //LJWebSettings.setUserAgentString( StringToJString( L_UA+’ ; 你追加的UserAgent的自定义部分的字符串’ ) );

end;

user-agent,可以用getUserAgentString()方法获取,在手机上打印出来的结果是:

Mozilla/5.0 (Linux; Android 8.1.0; NX606J Build/OPM1..026; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/61.0.3163.98 Mobile Safari/537.36

delphi FMX.WebBrowser与H5交互JavaScript

通过上面的getUserAgentString方法可以捕获你的运行平台下的当前默认设置的浏览器的内核的用户代理User-Agent

为何需要判断和设置用户代理User-Agent:1、因为它是可以被伪装了;2、它决定了:同一个网页页面在不同浏览器内核下的排版显示效果===》用户体验、统计信息,简称UA,比如:统一页面,用手机访问网页和电脑访问是不一样的。

补充常识:“html的head如何设置和调测不同浏览器内核的用户代理User-Agent” :https://jingyan.baidu.com/article/f0e83a25cb189363e491010b.html

“不同浏览器内核下的html的head设置用户代理User-Agent的兼容性” :https://www.cnblogs.com/pinpin/p/10773327.html

“不同浏览器内核下的html的head设置用户代理User-Agent的兼容性(截止2019年7月)” :https://blog.csdn.net/_34502571/article/details/95725337

如何在网页代码中提示用户浏览器的H5兼容性:

  

H5兼容问题及解决方法: https://www.cnblogs.com/dreambin/p/9035446.html  :原文:https://blog.csdn.net/_42936527/article/details/89393130

微信H5页面前端开发,大多数人都会遇到的几个兼容性坑: https://segmentfault.com/a/86963

 

(2)、新增 重定向 Redirection 功能:

    // 请设置好 RedirectionKey,千万不要用 URL 上的一些关键字,也不要用特殊字符:

    可直接拿来用,用于FMX.WebBrowser与H5交互JavaScript。

 

二、应用

2.1、腾讯开源H5图形图形处理库AlloyImage

 

《图片处理不用愁,给你十个小帮手》https://cloud.tencent.com/developer/article/1649704 

其中,有很多案例在线测试。

delphi FMX.WebBrowser与H5交互JavaScript

 

2.2、……(2021-01-12)写累了,明儿继续……

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/216505.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 上午11:42
下一篇 2026年3月18日 上午11:42


相关推荐

  • 管程 java_Synchronized之管程

    管程 java_Synchronized之管程Java 对象如何与 Monitor 关联如图所示 依次对图中进行解释 java 对象与 monitor 的关联图我们知道 JVM 堆中存放的是对象实例 对象实例包括几个部分 分别是与对象实例无关的对象头 实例数据 填充数据 对象头中包括几个部分 MarkWord 和指向元数据的指针 所占内存为 2 JVM 位数 在 32bitJVM 中就占 8 个字节 MarkWord 和指向元数据的指针分别占一个 JVM 位数 注意 如果

    2026年3月18日
    1
  • 白化Whitening

    白化Whitening白化操作的目的是让我们的减少冗余信息 准确来说通过白化操作我们有两个目的 每个特征之间关联性更少每个特征有相同的方差对于第一个目的来说 我们可以通过熟悉的 PCA 来实现 PCAPrincipal PCA 是一个用来减少特征纬度的算法 它通过减少特征的纬度来减少冗余信息 比如说 下图所示的一个特征纬度为 2 的点分类问题 我们可以看到数据的主要

    2026年3月18日
    2
  • socat 使用「建议收藏」

    转原文链接:http://www.wenquan.name/?p=1158用socat试几个netcat常用的用法,对比如下:1.听tcp12345端口#nc-l127.0.0.112345#socattcp-listen:12345-2.向远处tcp12345端口发点字#echo“test”|nc127.0.0.112345#echo“t…

    2022年4月8日
    57
  • adb安装与配置[通俗易懂]

    adb安装与配置[通俗易懂]一、前置条件安装JavaJDK,可以参考文章:https://blog.csdn.net/dou_being/article/details/105320962二、下载安装AndroidSDK或AndroidStudio,下载地址:http://tools.android-studio.org/三、配置环境变量1、Windows系统环境变量配置(1)在系统环境变量中新建变量名为adb,变量值为AndroidSDK的platform-tools文件夹和build-tools文件.

    2022年5月17日
    106
  • T10接口_服务端接口和前端接口

    T10接口_服务端接口和前端接口本文适用鼎捷软件T100系列1.azzi700注册接口程序号,接口服务名2.设计器code进行签出,下载(空框架)3.设计数据接收的结构,以及开发函数进行数据处理4.程序上传,无提示则表示成功5.打开http://erp_ip/wstopprd/ws/r/awsp920,如果接口地址返回isok则接口是通过的,还可以使用工具postman或者soapui进行调用测试6.检查日志,T100的接口日志存放于$TEMPDIR或者$TEMPLOG,日志的命名规则是按天的,每天调用的所

    2022年10月20日
    6
  • 科大讯飞(002230):AI驱动收入持续提速 星火X1迎重大升级

    科大讯飞(002230):AI驱动收入持续提速 星火X1迎重大升级

    2026年3月14日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号