CEF 修改请求 header 与单独处理 header 中的 referer
- 2020 年 1 月 4 日
- 筆記
有些时候利用 CEF 内嵌的页面加载某些资源的时候需要附带一些头信息,比如里面的图片需要携带一些校验和信息才能正常访问的,这个时候就需要在发起请求前对 HTTP Request 的 Header 部分进行修改。CEF 提供了两个接口用于读写 Request Header,分别是 CefLifeSpanHandler::OnAfterCreated
和 CefRequestHandler::OnBeforeResourceLoad
方法。两个都是虚函数,需要继承并重写两个方法来实现对 Request Header 的读取和修改。
区别
OnAfterCreated
和 OnBeforeResourceLoad
的区别是,OnAfterCreated
中传递的 request 参数是只读的, 这里只能对数据进行读取而不能修改。而 OnBeforeResourceLoad
中 request 参数是可以修改的。所以如果你需要添加或修改一些头信息需要在这里进行处理。
修改
修改的过程十分简单,只需要先把原来的 Header 信息读取出来,然后将你需要修改的信息删除再添加进去就可以了,如果只是新增内容,直接 emplace 就可以了。要注意的是,header 是一个 multimap 结构,允许有重复值,所以修改要么是基于原来修改,要么是删除再添加。
CefRequestHandler::ReturnValue ProfileMine::OnBeforeLoadResource(CefRefPtr<CefRequest> request, bool is_redirect) { if (app_sdk::AppSDKInterface::IsSafeUrl(request->GetURL().ToString())) { // backup headers CefRequest::HeaderMap headers; request->GetHeaderMap(headers); // .... do something // add new headers headers.emplace("AppKey", appkey); headers.emplace("Nonce", nonce); headers.emplace("CurTime", curtime); headers.emplace("CheckSum", checksum); // reset headers request->SetHeaderMap(headers); // referer 要单独设置,不允许使用 SetHeaderMap 接口设置 referer 内容见 SetHeaderMap 注释 request->SetReferrer(referer, REFERRER_POLICY_ALWAYS); QLOG_APP(L"ProfileMine::OnBeforeLoadResource short URL = {0}") << request->GetURL().ToString16(); } return RV_CONTINUE; }
注意事项
上面代码大家也注意到了,我没有将 referer
的值通 SetHeaderMap
方法来修改,而是后面调用单独的 SetReferrer
方法来修改,这源于 CEF 内部的限制,看一下 SetHeaderMap
的注释:
/// // Set the header values. If a Referer value exists in the header map it will // be removed and ignored. /// /–cef()–/ virtual void SetHeaderMap(const HeaderMap& headerMap) =0;
另外要注意的是,修改了 header 内容以后,通过 CEF 内置的调试工具抓包是看不到修改后的内容的,如果是 https 协议,你只能去服务器看一下接收到的参数中是否有你携带的 headers。这个要注意,我们在这个上面花费了很长时间,最后才发现调试工具是看不到的。