CEF3—在网页加载前给js对象填值

文章目录

  • CEF3—在网页加载前给js对象填值
    • 前言
    • 思路
    • 代码

CEF3—在网页加载前给js对象填值

前言

记录一次笔者在实际开发中遇到的问题。在用cef做多页应用开发的时候,多个单页共享数据的问题。这个数据被前端称之为token,在多页应用中需要被共享。数据被使用和存的动作都是在render进程,而多个h5页面也就是多个 render进程中,但是存放的位置肯定是在browser进程,因为browser进程是后台进程,大家取数据都到同一个进程中去存取 数据也就被共享。

思路

笔者一开始设计的接口如下:

BB.SetToken(x); // 存token
BB.Token(function(x){console.log(x);}); // 取token

存 会去更新token。 取 需要通过回调函数取,这里需要在回调函数中去,因为数据并不在render进程中 只能异步取。看是去一切还很简单 美好。但是 前端并不想通过回调函数的方式取token,就想通过类似下面的方式去取。

// 前端想快速方便的取到token,类似下面这种方式
var token = BB.Token(); // 方法返回值方式
var token = BB.token;	// 对象属性的方式

当然前端的要求并不过分,就得我们去想办法去实现了!这里如果用方法的返回值的话,必须使用全局的事件进行等待,等从browser取到了还要从共享内存或者其他方式把token数据取到。所以笔者当然也想用最简单方式去实现,这里是使用 BB.token对象属性值的方式。

如果用对象属性的方式的话,我们 token的填值 就是我们客户端作为主动方进行填值。如果 有单页使用SetToken方法更新token,那么此时 客户端要更新所有单页上的 BB.token。如果新开一个单页而且js代码要立即取到BB.token的值,这里也就是笔者遇到的问题。因为笔者 更新某个单页的上的BB.token逻辑已写好,当新单页打开加载后 直接给新开的单页 发送消息让其更新token即可,但是这样回有一个延时问题 在页码加载过程中 js代码取不到token而要等1s后才能取到。

代码

所以 不能等单页加载完后 去发送更新token的消息去进行更新。这里必须是在 创建单页或者在单页加载完前 类似window对象的内置属性一样 可以直接取到token。网上没找到参考的,所以笔者去仔细看了一下cef接口 果然找到了。主要用到下面几个接口。

// 创建单页会用到下面这个接口,对就是这个函数,仔细看这个函数的extra_info参数,该数据可以将browser进程的数据带到创建单页过程中的回调函数中CefRenderProcessHandler::OnBrowserCreated()


// CefBrowserHost的静态成员函数
  ///
  // Create a new browser window using the window parameters specified by
  // |windowInfo|. All values will be copied internally and the actual window
  // will be created on the UI thread. If |request_context| is empty the
  // global request context will be used. This method can be called on any
  // browser process thread and will not block. The optional |extra_info|
  // parameter provides an opportunity to specify extra information specific
  // to the created browser that will be passed to
  // CefRenderProcessHandler::OnBrowserCreated() in the render process.
  ///
  /*--cef(optional_param=client,optional_param=url,
          optional_param=request_context,optional_param=extra_info)--*/
static bool CreateBrowser(const CefWindowInfo& windowInfo,
                            CefRefPtr client,
                            const CefString& url,
                            const CefBrowserSettings& settings,
                            CefRefPtr extra_info,
                            CefRefPtr request_context);



// 所以就找到CefRenderProcessHandler中相关的回调函数

// CefRenderProcessHandler中可被重写的回调函数

// 该函数可以取到从browser进程中带过来的数据
  ///
  // Called after a browser has been created. When browsing cross-origin a new
  // browser will be created before the old browser with the same identifier is
  // destroyed. |extra_info| is a read-only value originating from
  // CefBrowserHost::CreateBrowser(), CefBrowserHost::CreateBrowserSync(),
  // CefLifeSpanHandler::OnBeforePopup() or CefBrowserView::CreateBrowserView().
  ///
  /*--cef()--*/
  virtual void OnBrowserCreated(CefRefPtr browser,
                                CefRefPtr extra_info) {}



// 下面这个函数注释写的很清楚,下面是Chrome V8环境一旦被创建好就会被回调,所以在下面回调函数中取我们的自定义对象或者 window对象一定是可以取到并能赋值的
  ///
  // Called immediately after the V8 context for a frame has been created. To
  // retrieve the JavaScript 'window' object use the CefV8Context::GetGlobal()
  // method. V8 handles can only be accessed from the thread on which they are
  // created. A task runner for posting tasks on the associated thread can be
  // retrieved via the CefV8Context::GetTaskRunner() method.
  ///
  /*--cef()--*/
  virtual void OnContextCreated(CefRefPtr browser,
                                CefRefPtr frame,
                                CefRefPtr context) {}

关键代码如下:

// browser进程中创建单页	
CefRefPtr extra_info = CefDictionaryValue::Create();
extra_info->SetString("token",m_strToken);
CefBrowserHost::CreateBrowser(windowInfo, m_browserEvent, strUrl, browserSetting, extra_info, NULL);

// render进程中处理数据并给js对象进行属性赋值
static CefString m_strToken = "";
void CCefBrowserApp::OnBrowserCreated(CefRefPtr browser, CefRefPtr extra_info)
{
	m_strToken = extra_info->GetString(CefString("token"));
}

void CCefBrowserApp::OnContextCreated(CefRefPtr browser, CefRefPtr frame, CefRefPtr context)
{
	context->Enter();
	CefRefPtr window = context->GetGlobal();
	CefRefPtr BB = window->GetValue(CefString("BB"));
	if(BB->IsObject())
	{
	CefRefPtr token = CefV8Value::CreateString(m_strToken);
	BB->SetValue(_T("token"),token,CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_DONTDELETE);	
	}
	context->Exit();
}

你可能感兴趣的:(【L_CEF】,CEF3,CefBrowserHost,CefRenderProces,render进程,browser进程)