前言:
今天姐妹们对“js一个方法执行完执行另一个方法”都比较讲究,兄弟们都想要分析一些“js一个方法执行完执行另一个方法”的相关知识。那么小编也在网上收集了一些关于“js一个方法执行完执行另一个方法””的相关资讯,希望各位老铁们能喜欢,朋友们快快来了解一下吧!在puppeteer中的实现
实现类似在puppeteer中,page.evaluateOnNewDocument(pageFunction[, ...args]) 。指定的函数在所属的页面被创建并且所属页面的任意 script 执行之前被调用。常用于修改页面js环境。
下面是在页面加载前重写 navigator.languages 属性的例子:
preload.js:
// 重写 `languages` 属性,使其用一个新的get方法Object.defineProperty(navigator, "languages", { get: function() { return ["en-US", "en", "bn"]; }});
// 假设 preload.js 和当前的代码在同一个目录const preloadFile = fs.readFileSync('./preload.js', 'utf8');await page.evaluateOnNewDocument(preloadFile);在jcef中的实现
同puppeteer有所不同,由于jcef中executeJavaScript是异步的,为确保注入成功(在页面的js执行前执行),sleep一定时间。
准备个html
定义一个html,其中有个变量injectDataJcef5,如果展示的是html中的原始值,说明注入失败:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>测试打开静态文件</title></head><body> <h1>测试sendMessage2Java+inject</h1> <button onclick="globalVar.f.sendMessage2Java(injectDataJcef5)">sendInject</button> <script> var injectDataJcef5 = injectDataJcef5 || "无数据"; if(injectDataJcef5 == "无数据"){ alert('注入失败!'); throw new Error("注入失败!"); } var globalVar = globalVar || {}; globalVar.f = globalVar.f || {} globalVar.v = globalVar.v || {} globalVar.v.fieldNm_fQuery = 'fQuery'; globalVar.v.fieldNm_fQueryCancel = 'fQueryCancel'; globalVar.f.parseUrlParamObj = function(){ // 1. 获取URL中的所有参数 const urlSearchParams = new URLSearchParams(window.location.search); // 2. 定义一个空对象来存储参数 const params = {}; // 3. 遍历参数并将其添加到对象中 for (const [key, value] of urlSearchParams.entries()) { params[key] = value; } // 4. 返回参数对象 return params; } const urlParamObj = globalVar.f.parseUrlParamObj(); if(urlParamObj.hasOwnProperty(globalVar.v.fieldNm_fQuery)){ urlParamObj[globalVar.v.fieldNm_fQuery]; }else{ throw new Error("未找到参数【" + globalVar.v.fieldNm_fQuery + "】"); } if(urlParamObj.hasOwnProperty(globalVar.v.fieldNm_fQueryCancel)){ urlParamObj[globalVar.v.fieldNm_fQueryCancel]; }else{ throw new Error("未找到参数【" + globalVar.v.fieldNm_fQueryCancel + "】"); } globalVar.f.sendMessage2Java = function(request){ // 即 window.csh_Query({...}) window[urlParamObj[globalVar.v.fieldNm_fQuery]]({ request: request, onSuccess: function(response) { alert("onSuccess:" + response); globalVar.v.sendMessage2Java_response_onSuccess = response; }, onFailure: function(error_code, error_message) { alert("error_code:" + error_code); alert("error_message:" + error_message); globalVar.v.sendMessage2Java_error_code = error_code; globalVar.v.sendMessage2Java_error_message = error_message; } }); } </script></body></html>CshJcefJsInjectHandlerDemo
client_ 中 addRequestHandler:
// 任意 script 执行之前被调用指定的jsclient_.addRequestHandler(new CshJcefJsInjectHandlerDemo());
核心代码
if (frame.isMain()) { LOGGER.info("注入JavaScript代码 frame.getURL()===:" + frame.getURL()); try { // 让线程 sleep 一秒保证 executeJavaScript 方法能够执行 Thread.sleep(1000); Thread.sleep(100);// test 3 ok// Thread.sleep(10);// test 不成,会注入失败 } catch (InterruptedException e) { LOGGER.info("sleep失败", e); } // 注入JavaScript代码 // url(第二个参数):这个参数为代码提供了上下文,它通常用于开发者工具中,以显示代码来源。这个URL不会被用来下载脚本,它是一个虚拟的源参考,有助于调试。例如,如果在控制台中抛出了错误,这个URL就会被用来表示代码的来源。 // startLine(第三个参数):这个参数是一个整数,指定了代码在源文件中的起始行号。这对于调试也很有用,因为它可以帮助开发者确定代码中的错误位置。如果你没有具体的行号信息,通常使用0作为默认值。 //【】 尽管 executeJavaScript 在 onBeforeBrowse 中被调用,但它只能确保在此时刻执行,无法控制相对于页面中其他已有脚本的执行顺序。 frame.executeJavaScript("var injectDataJcef5 = injectDataJcef5 || '注入的数据';", frame.getURL(), 0); }
完整代码:
package com.virhuiai.JBCefBrowser.handler;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.cef.browser.CefBrowser;import org.cef.browser.CefFrame;import org.cef.callback.CefAuthCallback;import org.cef.callback.CefCallback;import org.cef.handler.CefLoadHandler;import org.cef.handler.CefRequestHandler;import org.cef.handler.CefResourceRequestHandler;import org.cef.handler.CefResourceRequestHandlerAdapter;import org.cef.misc.BoolRef;import org.cef.network.CefRequest;import org.cef.network.CefResponse;// 实现了CefRequestHandler接口和CefResourceRequestHandler接口,// 用于处理浏览器的请求事件。public class CshJcefJsInjectHandlerDemo extends CefResourceRequestHandlerAdapter implements CefRequestHandler { private static Log LOGGER = LogFactory.getLog(CshJcefJsInjectHandlerDemo.class); // 在浏览器发起导航前调用,可以在此方法中拦截请求 // 当浏览器即将加载一个页面之前,这个方法被调用。 // bard : // onBeforeBrowse方法可以用来实现以下功能: //阻止浏览器加载某些页面。 //修改页面的 URL。 //在页面加载之前执行自定义代码。 //执行时机的问题: onBeforeBrowse 方法是在浏览器即将发起导航请求时调用的, // 这意味着它是在任何页面内容(包括 JavaScript 文件和 HTML 内容)被加载之前执行的。 // 然而,这个方法中注入的 JavaScript 代码实际上是在页面开始加载时注入的,但并不能保证在所有其他 JavaScript 执行之前运行。 @Override public boolean onBeforeBrowse(CefBrowser browser, CefFrame frame, CefRequest request, boolean user_gesture, boolean is_redirect) { //主框架是指浏览器中加载的页面的顶级框架,通常是整个页面的主要内容。 // 当浏览器加载页面时,会创建一个主框架,并在主框架中显示页面的内容。 // //因此,frame.isMain()为假值的情况是当frame表示的是非主框架,例如内嵌在页面中的一个框架或iframe等。 if (frame.isMain()) { LOGGER.info("注入JavaScript代码 frame.getURL()===:" + frame.getURL()); try { // 让线程 sleep 一秒保证 executeJavaScript 方法能够执行 Thread.sleep(1000); Thread.sleep(100);// test 3 ok// Thread.sleep(10);// test 不成,会注入失败 } catch (InterruptedException e) { LOGGER.info("sleep失败", e); } // 注入JavaScript代码 // url(第二个参数):这个参数为代码提供了上下文,它通常用于开发者工具中,以显示代码来源。这个URL不会被用来下载脚本,它是一个虚拟的源参考,有助于调试。例如,如果在控制台中抛出了错误,这个URL就会被用来表示代码的来源。 // startLine(第三个参数):这个参数是一个整数,指定了代码在源文件中的起始行号。这对于调试也很有用,因为它可以帮助开发者确定代码中的错误位置。如果你没有具体的行号信息,通常使用0作为默认值。 //【】 尽管 executeJavaScript 在 onBeforeBrowse 中被调用,但它只能确保在此时刻执行,无法控制相对于页面中其他已有脚本的执行顺序。 frame.executeJavaScript("var injectDataJcef5 = injectDataJcef5 || '注入的数据';", frame.getURL(), 0); } // 返回false表示不拦截请求,继续加载页面。 return false;// return true; } @Override public boolean onResourceResponse(CefBrowser browser, CefFrame frame, CefRequest request, CefResponse response) {// response.get return false; } @Override public boolean onBeforeResourceLoad(CefBrowser browser, CefFrame frame, CefRequest request) { // 返回 false 以继续加载资源 return false; } @Override public boolean onOpenURLFromTab(CefBrowser cefBrowser, CefFrame cefFrame, String s, boolean b) { return false; } @Override public CefResourceRequestHandler getResourceRequestHandler(CefBrowser cefBrowser, CefFrame cefFrame, CefRequest cefRequest, boolean b, boolean b1, String s, BoolRef boolRef) { return null; } @Override public boolean getAuthCredentials(CefBrowser cefBrowser, String s, boolean b, String s1, int i, String s2, String s3, CefAuthCallback cefAuthCallback) { return false; } @Override public boolean onCertificateError(CefBrowser cefBrowser, CefLoadHandler.ErrorCode errorCode, String s, CefCallback cefCallback) { return false; } @Override public void onRenderProcessTerminated(CefBrowser cefBrowser, TerminationStatus terminationStatus) { }}
Jcef跨平台H5(HTML5)开发中,
版权声明:
本站文章均来自互联网搜集,如有侵犯您的权益,请联系我们删除,谢谢。
标签: #js一个方法执行完执行另一个方法