Disclosure Statement: This site contains affiliate links, which means that I may receive a commission if you make a purchase using these links. As an eBay Partner, I earn from qualifying purchases.
If you find these projects useful please consider becoming a sponsor with Patreon, GitHub or Liberapay.

Set different user agent

Post Reply
thefunkyjoint
Posts: 513
Joined: Thu Aug 10, 2017 12:40 pm

Set different user agent

Post by thefunkyjoint »

Hello,

I know i can use GlobalCEFApp.UserAgent to set the user agent. But is there a way to set different user agent for different instances of TChromium ?

Or change the user agent during runtime, after GlobalCEFApp.StartMainProcess ?

Thanks !
User avatar
salvadordf
Posts: 4565
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: Set different user agent

Post by salvadordf »

You can try the TChromium.OnBeforeResourceLoad event to modify the HTTP headers.

Here's an example that modifies the "Accept-Encoding" header :
https://github.com/salvadordf/CEF4Delph ... r.pas#L448
thefunkyjoint
Posts: 513
Joined: Thu Aug 10, 2017 12:40 pm

Re: Set different user agent

Post by thefunkyjoint »

Thank you very much for the info !

I updated the code to alter the user agent and it's ALMOST working : the website opens the version with the new user-agent i set, but a fraction of second after reloads the version with the default user-agent. It seems something is missing.

I can achieve the desired result by setting GlobalCEFApp.UserAgent before GlobalCEFApp.StartMainProcess.

But somehow, using the method below won't work, maybe is there any other place i need to change the header ?

Just to clarify, what i want is to make one of the instances of TChromium in my app, simulate an Iphone browser. But only one, other ones would use the default user agent.

Code: Select all

procedure TChromium1.OnBeforeResourceLoad(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame;
  const request: ICefRequest; const callback: ICefRequestCallback; out Result: TCefReturnValue);
var
  TempOldMap, TempNewMap : ICefStringMultimap;
  i : NativeUInt;
  TempReplaced : boolean;
  userAgent : strin;g
begin
  Result := RV_CONTINUE;
   userAgent := 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/76.0.3809.123 Mobile/15E148 Safari/605.1' ;
  if userAgent <> '' then
    try
      // We replace the Accept-Encoding HTTP header to request uncompressed resources.
      // If the server sends uncompressed resources it should be easier to handle the
      // end of the resource reception because we may know its length.

      TempNewMap := TCefStringMultimapOwn.Create;
      TempOldMap := TCefStringMultimapOwn.Create;

      request.GetHeaderMap(TempOldMap);

      TempReplaced := False;
      i := 0;
      while (i < TempOldMap.Size) do
        begin
          if (CompareText(TempOldMap.Key[i], 'User-Agent') = 0) then
            begin
              TempNewMap.Append('User-Agent', userAgent);
              TempReplaced := True;
            end
           else
            TempNewMap.Append(TempOldMap.Key[i], TempOldMap.Value[i]);

          inc(i);
        end;

      if not(TempReplaced) then TempNewMap.Append('User-Agent', userAgent);
      request.SetHeaderMap(TempNewMap);
    finally
      TempNewMap := nil;
      TempOldMap := nil;
    end;
end;
User avatar
salvadordf
Posts: 4565
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: Set different user agent

Post by salvadordf »

Apparently, if the website gets the user agent using JavaScript it gets the User Agent from the GlobalCEFApp property (CefSettings). :oops:
https://magpcss.org/ceforum/viewtopic.p ... 78&p=34163
https://www.magpcss.org/ceforum/viewtop ... =6&t=14685

Another user modified the CEF binaries to set the User Agent in every request :
https://magpcss.org/ceforum/viewtopic.p ... 717#p43032

If you don't want to modify the CEF binaries you can create a different application with a CEF browser using your custom User Agent. Your main application would run the new application and it would have to communicate with it using some kind of inter-process communication method.
thefunkyjoint
Posts: 513
Joined: Thu Aug 10, 2017 12:40 pm

Re: Set different user agent

Post by thefunkyjoint »

salvadordf wrote: Tue Sep 03, 2019 12:44 pm Apparently, if the website gets the user agent using JavaScript it gets the User Agent from the GlobalCEFApp property (CefSettings). :oops:
https://magpcss.org/ceforum/viewtopic.p ... 78&p=34163
https://www.magpcss.org/ceforum/viewtop ... =6&t=14685

Another user modified the CEF binaries to set the User Agent in every request :
https://magpcss.org/ceforum/viewtopic.p ... 717#p43032

If you don't want to modify the CEF binaries you can create a different application with a CEF browser using your custom User Agent. Your main application would run the new application and it would have to communicate with it using some kind of inter-process communication method.
I will use this workaround for now (two separate apps). If someday in the future you make it fully possible each instance having its own user agent, please let me know, would be awesome ! :D
thefunkyjoint
Posts: 513
Joined: Thu Aug 10, 2017 12:40 pm

Re: Set different user agent

Post by thefunkyjoint »

Do you think it could be possible in near future (each instance has it own user agent) or is it technically hard to implement ?
User avatar
salvadordf
Posts: 4565
Joined: Thu Feb 02, 2017 12:24 pm
Location: Spain
Contact:

Re: Set different user agent

Post by salvadordf »

That's a CEF feature and I can't override it from the CEF4Delphi side.

There's a pull request to override the user agent :
https://bitbucket.org/chromiumembedded/ ... tring/diff

Perhaps it's what you need but I don't know when it will be merged into the master branch.
Even then, it will take some months until it reaches the stable branch.
thefunkyjoint
Posts: 513
Joined: Thu Aug 10, 2017 12:40 pm

Re: Set different user agent

Post by thefunkyjoint »

I understand. I'll stick with the second app option :P
Post Reply