Receiving Callback URI from Navigation
Posted: Thu Nov 12, 2020 9:17 am
Hello,
in order to communicate with an online API I have to receive callbacks send by the page while I'm navigating in it. As written in the API's documentation, they contain the keyword "callback" e.g. "http://api.ausschreiben.de/v2/callback/ ... /startpage".
My Problem there is, that I don't receive them at all.
I'm using the latest CEF4Delphi on Tokyo 10.2.3 and tested in "SimpleBrowser" Demo.
I expected to receive them in the OnBeforeBrowes-Event or the OnAdressChange-Event but i am getting none.
In the API's demo (which is working), the C# looks like this:
Is there anything I can do to get to them navigation-callbacks?
kind regards
in order to communicate with an online API I have to receive callbacks send by the page while I'm navigating in it. As written in the API's documentation, they contain the keyword "callback" e.g. "http://api.ausschreiben.de/v2/callback/ ... /startpage".
My Problem there is, that I don't receive them at all.
I'm using the latest CEF4Delphi on Tokyo 10.2.3 and tested in "SimpleBrowser" Demo.
I expected to receive them in the OnBeforeBrowes-Event or the OnAdressChange-Event but i am getting none.
In the API's demo (which is working), the C# looks like this:
Code: Select all
/// <summary>
/// eventhandler to receive callbacks
/// </summary>
private void WebBrowser_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
if (mNavigationCallbackHandler != null)
{
//if it is a callback, the navigation has to be intercepted
if (mNavigationCallbackHandler.Callback(e.Url))
e.Cancel = true;
}
}
Code: Select all
type
TForm1 = class(TForm)
ChromiumWindow1: TChromiumWindow;
AddressPnl: TPanel;
AddressEdt: TEdit;
GoBtn: TButton;
Timer1: TTimer;
btnApi: TButton;
procedure btnApiClick(Sender: TObject);
procedure GoBtnClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure FormCreate(Sender: TObject);
procedure ChromiumWindow1AfterCreated(Sender: TObject);
procedure ChromiumWindow1Close(Sender: TObject);
procedure ChromiumWindow1BeforeClose(Sender: TObject);
procedure wb1BeforeNavigate2(ASender: TObject; const pDisp: IDispatch; const
URL, Flags, TargetFrameName, PostData, Headers: OLEVariant; var Cancel:
WordBool);
private
FApiSession: string;
// You have to handle this two messages to call NotifyMoveOrResizeStarted or some page elements will be misaligned.
procedure WMMove(var aMessage : TWMMove); message WM_MOVE;
procedure WMMoving(var aMessage : TMessage); message WM_MOVING;
// You also have to handle these two messages to set GlobalCEFApp.OsmodalLoop
procedure WMEnterMenuLoop(var aMessage: TMessage); message WM_ENTERMENULOOP;
procedure WMExitMenuLoop(var aMessage: TMessage); message WM_EXITMENULOOP;
function HttpPostExecute(AUrl, PostBodyData: string): string;
function GetResultUriFromResponse(response: string): string;
function GetApiSessionFromResponse(response: string): string;
procedure BeforeHeaderSendHandler(Sender: TObject; const Method: string; Headers: TStrings);
protected
// Variables to control when can we destroy the form safely
FCanClose : boolean; // Set to True in TChromium.OnBeforeClose
FClosing : boolean; // Set to True in the CloseQuery event.
procedure Chromium_OnBeforePopup(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const targetUrl, targetFrameName: ustring; targetDisposition: TCefWindowOpenDisposition; userGesture: Boolean; const popupFeatures: TCefPopupFeatures; var windowInfo: TCefWindowInfo; var client: ICefClient; var settings: TCefBrowserSettings; var extra_info: ICefDictionaryValue; var noJavascriptAccess: Boolean; var Result: Boolean);
procedure chrOnAdressChange(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const url: ustring);
procedure chrOnQuotaRequest(Sender: TObject; const browser: ICefBrowser; const originUrl: ustring; newSize: Int64; const callback: ICefRequestCallback; out Result: Boolean);
procedure chrOnResourceResponse(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; const response: ICefResponse; out Result: Boolean);
procedure chrOnBeforeBrowse(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; user_gesture, isRedirect: Boolean; out Result: Boolean);
procedure chrOnLoadStart(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; transitionType: TCefTransitionType);
procedure chrResourceRedirect(Sender: TObject; const browser: ICefBrowser; const frame: ICefFrame; const request: ICefRequest; const response: ICefResponse; var newUrl: ustring);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
uCEFApplication,
IdHTTP,
SuperObject,
OverbyteIcsHttpProt,
uCEFRequest,
uCEFStringMultimap,
uCEFStringMap,
uCEFPostData,
StrUtils;
const
SOFTWARE_ID = '865f215d-da17-11e5-8132-00241dc1eecb';
BASE_URL = 'http://api.ausschreiben.de/v2/';
STARTSESSION_ROUTE = 'startsession/';
ENDSESSION_ROUTE = 'endsession/';
EXPORT_DATA_ROUTE = 'export/';
HTTP_RESPONSE_OK = 200;
procedure TForm1.btnApiClick(Sender: TObject);
var
response, uri : string;
begin
// starting the API-session via HTTP-Post
response := HttpPostExecute('http://api.ausschreiben.de/v2/startsession/software/' + SOFTWARE_ID + '/viewmode/default/location/startpage/registercallbacks/dragstart,export,locationchanged', '');
// receive the session ID
FApiSession := GetApiSessionFromResponse(response);
// navigate to the opened session
uri := GetResultUriFromResponse(response);
ChromiumWindow1.LoadURL(uri);
end;
procedure TForm1.chrOnBeforeBrowse(Sender: TObject; const browser: ICefBrowser;
const frame: ICefFrame; const request: ICefRequest; user_gesture,
isRedirect: Boolean; out Result: Boolean);
begin
// detecting the callback on navigation
if AnsiContainsStr(request.Url, 'callback') then
begin
// do something
end;
end;
function TForm1.GetResultUriFromResponse(response: string): string;
var
O: ISuperObject;
begin
O := SO(response);
Result := O.S['ResultUri'];
end;
function TForm1.GetApiSessionFromResponse(response: string): string;
var
O: ISuperObject;
begin
O := SO(response);
Result := O.S['ApiSession'];
end;
procedure TForm1.BeforeHeaderSendHandler(Sender: TObject;
const Method: string; Headers: TStrings);
begin
Headers.Add('Accept: application/json');
if FApiSession <> '' then begin
Headers.Add('X-API-Session: ' + FApiSession);
end;
end;
function TForm1.HttpPostExecute(AUrl, PostBodyData: string): string;
var
httpClient: TSslHttpCli;
responseData: TStringStream;
begin
Result := '';
httpClient := TSslHttpCli.Create(nil);
responseData := TStringStream.Create('');
try
httpClient.RcvdStream := responseData;
httpClient.SendStream := TStringStream.Create('');
httpClient.URL := AUrl;
TStringStream(httpClient.SendStream).WriteString(PostBodyData);
httpClient.SendStream.Position := 0;
httpClient.OnBeforeHeaderSend := BeforeHeaderSendHandler;
try
httpClient.Post;
except
// nothing to do here
end;
if httpClient.StatusCode = HTTP_RESPONSE_OK then begin
result := responseData.DataString;
end;
finally
responseData.Free;
httpClient.SendStream.Free;
httpClient.Free;
end;
end;
procedure TForm1.chrOnAdressChange(Sender: TObject; const browser: ICefBrowser;
const frame: ICefFrame; const url: ustring);
begin
//
end;
kind regards