CEF 修改請求 header 與單獨處理 header 中的 referer

有些時候利用 CEF 內嵌的頁面載入某些資源的時候需要附帶一些頭資訊,比如裡面的圖片需要攜帶一些校驗和資訊才能正常訪問的,這個時候就需要在發起請求前對 HTTP Request 的 Header 部分進行修改。CEF 提供了兩個介面用於讀寫 Request Header,分別是 CefLifeSpanHandler::OnAfterCreatedCefRequestHandler::OnBeforeResourceLoad 方法。兩個都是虛函數,需要繼承並重寫兩個方法來實現對 Request Header 的讀取和修改。

區別

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

相關