Delphi 10.2.2 Tokyo中FireMonkey TWebBrowser回调无URL返回问题求助
首先,我注意到你代码里的一个关键问题:你错误地编码了整个URL,导致浏览器无法识别这是一个合法的导航请求,所以ShouldStartLoadWithRequest事件没有被正确触发。让我们一步步拆解问题并修正:
1. 修正JavaScript代码的URL构造
你的JS代码把整个file://URL都用encodeURIComponent编码了,这会把协议部分(file://)也转换成百分号编码的字符串,浏览器根本无法识别这是一个本地文件导航请求。正确的做法是只编码需要传递的参数(如果参数有特殊字符的话),或者直接拼接参数到原始URL后:
procedure TForm2.Button1Click(Sender: TObject); var js : string; baseUrl: string; begin baseUrl := 'file://' + GetCurrentDir + '/../../index.html'; // 直接拼接参数,不需要编码整个URL js := Format('window.location.href = "%s?%d";', [baseUrl, 67]); WebBrowser1.EvaluateJavaScript(js); end;
如果你的参数包含特殊字符,只编码参数部分即可:
js := Format('window.location.href = "%s?%s";', [baseUrl, encodeURIComponent('67')]);
2. 确保ShouldStartLoadWithRequest事件已正确绑定
这是很容易遗漏的细节:在设计器中,你需要确认WebBrowser1的ShouldStartLoadWithRequest事件已经关联到你的TForm2.WebBrowser1ShouldStartLoadWithRequest方法。如果没有绑定,即使URL正确,事件也不会触发。
3. 优化URL参数提取逻辑
你的Fetch函数是自定义的,为了避免依赖自定义函数,你可以用更可靠的方式提取参数:
procedure TForm2.WebBrowser1ShouldStartLoadWithRequest(ASender: TObject; const URL: string); var paramStart: Integer; paramValue: string; baseUrl: string; begin baseUrl := 'file://' + GetCurrentDir + '/../../index.html'; // 检查URL是否以我们的基础URL开头 if StartsStr(baseUrl + '?', URL) then begin paramStart := Pos('?', URL) + 1; paramValue := Copy(URL, paramStart, Length(URL) - paramStart + 1); // 解码参数(如果之前编码过的话) paramValue := TIdURI.URLDecode(paramValue, IndyTextEncoding_UTF8); Memo1.Lines.Text := paramValue; end; end;
4. 处理浏览器缓存/重复URL的问题
有些平台的FireMonkey TWebBrowser(比如Windows上的IE内核)可能会忽略导航到相同基础URL的请求,即使参数不同。你可以在URL后添加一个随机的时间戳参数来强制浏览器认为这是一个新请求:
js := Format('window.location.href = "%s?%d&t=%d";', [baseUrl, 67, DateTimeToUnix(Now)]);
这样每次请求的URL都带有唯一的时间戳,确保浏览器会触发导航事件。
验证思路
理论上,当你修改window.location.href到一个带参数的新URL时,浏览器会认为这是一个新的导航请求,从而触发ShouldStartLoadWithRequest事件。只要URL构造正确、事件绑定到位,你就能提取到参数67,同时页面会刷新(因为导航到了带参数的同一页面)。
内容的提问来源于stack exchange,提问作者user9234656

