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。這個要注意,我們在這個上面花費了很長時間,最後才發現調試工具是看不到的。