Question

I am trying to replace the data that webbrowser requests with a local file but the result is not displayed in the browser. So how to properly use TCefStreamReaderRef?

procedure TForm1.Chromium1BeforeResourceLoad(Sender: TObject;
  const browser: ICefBrowser; const request: ICefRequest;
  var redirectUrl: ustring; var resourceStream: ICefStreamReader;
  const response: ICefResponse; loadFlags: Integer; out Result: Boolean);
var
  strm: ICefStreamReader;
begin
  strm := TCefStreamReaderRef.CreateForFile('c:\sometxtfile.txt');
  resourceStream:=strm;

  result:=True;
end;
Was it helpful?

Solution

You're using the TCefStreamReaderRef correctly, but you're having two issues in the code. You must return False to the Result parameter and you're trying to load a text file for all requested resources.

The first problem is related to what is stated in the OnBeforeResourceLoad event reference (quote is emphasized by me):

OnBeforeResourceLoad

Called on the IO thread before a resource is loaded. To allow the resource to load normally return false. To redirect the resource to a new url populate the |redirectUrl| value and return false. To specify data for the resource return a CefStream object in |resourceStream|, use the |response| object to set mime type, HTTP status code and optional header values, and return false. To cancel loading of the resource return true. Any modifications to |request| will be observed. If the URL in |request| is changed and |redirectUrl| is also set, the URL in |request| will be used.

The second problem is that the site can for instance expect to load and render an image from a certain resource, but you have forcely tell the resource loader to load a text file instead. Now imagine what can renderer do with a text file resource for an image tag to be rendered. You just confused it, so it renders nothing.

For a proof of concept example you can try the following code e.g. It loads a sprite of the StackOverflow site from file (you can get an example green sprite image from here):

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, cefvcl, ceflib;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FChromium: TChromium;
    procedure BeforeResourceLoad(Sender: TObject; const browser: ICefBrowser;
      const request: ICefRequest; var redirectUrl: ustring; var resourceStream: ICefStreamReader;
      const response: ICefResponse; loadFlags: Integer; out Result: Boolean);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  FChromium := TChromium.Create(nil);
  FChromium.Parent := Self;
  FChromium.Anchors := [akLeft, akTop, akRight, akBottom];
  FChromium.SetBounds(8, 8, ClientWidth - 16, ClientHeight - 16);
  FChromium.Load('http://stackoverflow.com');
  FChromium.OnBeforeResourceLoad := BeforeResourceLoad;
end;

procedure TForm1.BeforeResourceLoad(Sender: TObject; const browser: ICefBrowser;
  const request: ICefRequest; var redirectUrl: ustring; var resourceStream: ICefStreamReader;
  const response: ICefResponse; loadFlags: Integer; out Result: Boolean);
begin
  // return False here, since returning True means cancel loading of the resource
  Result := False;
  // check if the site is requesting a specific resource and if so, then...
  if Request.Url = 'http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=6' then
  begin
    // load a resource from file and set the HTTP status code and MIME type
    ResourceStream := TCefStreamReaderRef.CreateForFile('sprites.png');
    response.Status := 200;
    response.MimeType := 'image/png';
  end;
end;

end.

The full project you can get from here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top