Mega Code Archive

 
Categories / Delphi / XML
 

HTMLXML async request via POSTGET

Title: HTML/XML async request via POST/GET Question: Component that use HttpXMLRequest to communicate with web server. Answer: complete source with example:: http://www.piramida-sistem.com/dax/TXMLTest.zip unit XMLRequestAsync; interface uses SysUtils, Classes,variants,msxml; type RequestStringArray=array of string; type eRequestType=(POST,GET,HEAD); IOnReadyStateChange=interface; TXMLRequestAsync = class; TEventObject=class(TInterfacedObject,IDispatch) private sObj:XMLHttpRequest; sEventCallback:IOnReadyStateChange; value:integer; RT:eRequestType; public function GetTypeInfoCount(out Count: Integer): HResult; stdcall; function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall; function GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall; function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall; end; IOnReadyStateChange = interface procedure OnReadyStateChange (const XMLHttp_obj:XMLHttpRequest;const EventObject:TEventObject); end; TRequestNotifyEvent = procedure(Sender:TObject;requestValue:integer;requestType:eRequestType;respondStatus:integer) of object; TXMLRequestAsync = class(TComponent,IOnReadyStateChange) private { Private declarations } XMLHTTP:XMLHttpRequest; HR:TRequestNotifyEvent; nParamNames,nParamValues:RequestStringArray; function IsBusy():longbool; function GetDoc():IXMLDOMDocument; function GetReq():XMLHttpRequest; protected { Protected declarations } procedure OnReadyStateChange (const XMLHttp_obj:XMLHttpRequest;const EventObject:TEventObject); procedure InitRequest(rType:eRequestType;const URL,USR,PWD:string); function ChangeURLChars(const nS:string):string; function GetParameters():string; procedure SendRequest(const rData:string); public { Public declarations } function SendHTTPRequest(rType:eRequestType;RequestValue:integer;const Url:string;const Username:string='';const Password:string=''):longbool; property Busy:longbool read IsBusy; property Document:IXMLDOMDocument read GetDoc; property Request:XMLHttpRequest read GetReq; property ParamNames:RequestStringArray read nParamNames write nParamNames; property ParamValues:RequestStringArray read nParamValues write nParamValues; published { Published declarations } property OnHTTPRespond :TRequestNotifyEvent read HR write HR; end; procedure Register; implementation procedure Register; begin RegisterComponents('Dodatne kontrole', [TXMLRequestAsync]); end; { TEventObject } function TEventObject.GetIDsOfNames(const IID: TGUID; Names: Pointer; NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; begin end; function TEventObject.GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; begin end; function TEventObject.GetTypeInfoCount(out Count: Integer): HResult; begin end; function TEventObject.Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer; Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; begin sEventCallback.OnReadyStateChange(sObj,self); result:=-1; end; { TXMLRequestAsync } function TXMLRequestAsync.ChangeURLChars(const nS: string): string; begin result:=stringreplace(nS,'+','%2B',[rfReplaceAll]); result:=stringreplace(result,'&','%26',[rfReplaceAll]); result:=stringreplace(result,' ','%20',[rfReplaceAll]); result:=stringreplace(result,'=','%3D',[rfReplaceAll]); end; function TXMLRequestAsync.GetDoc: IXMLDOMDocument; begin result:=nil; if (XMLHTTPnil) and (XMLHTTP.readyState=4) then result:=IXMLDOMDocument(XMLHTTP.responseXML); end; function TXMLRequestAsync.GetReq: XMLHttpRequest; begin result:=nil; if (XMLHTTPnil) then result:=XMLHTTP; end; procedure TXMLRequestAsync.InitRequest(rType:eRequestType;const URL,USR,PWD:string); var nT:string; cURL:string; cP:string; begin if rType=POST then nT:='POST' else if rType=GET then nT:='GET' else if rType=HEAD then nT:='HEAD'; if rType=GET then begin cURL:=URL; cP:=GetParameters(); if length(cP)0 then cURL:=cURL+'?'+cP; XMLHttp.open(nT,cURL,true,USR,PWD); end else XMLHttp.open(nT,URL,true,USR,PWD); XMLHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); end; function TXMLRequestAsync.IsBusy: longbool; begin if (XMLHTTP=nil) or (XMLHTTP.readyState in [0,4]) then result:=false else result:=true; end; procedure TXMLRequestAsync.OnReadyStateChange( const XMLHttp_obj: XMLHttpRequest; const EventObject: TEventObject); begin if XMLHttp_obj.readyState=4 then begin if assigned(HR) then HR(TObject(Self),EventObject.Value,EventObject.RT,XMLHttp_obj.status); XMLHttp_obj.onreadystatechange:=pointer(0); /////-----makni event! ina?e se pojavljuje memory leaking ! end; end; function TXMLRequestAsync.SendHTTPRequest(rType:eRequestType;RequestValue:integer;const Url:string;const Username:string='';const Password:string=''):longbool; var EventObject:TEventObject; begin result:=false; if (length(nParamNames)length(nParamValues)) or (length(URL)=0) then exit; try XMLHttp:=XMLHttpRequest(CoXMLHTTPRequest.Create()); EventObject:=TEventObject.Create; EventObject.sObj:=XMLHttp; EventObject.sEventCallback:=self; EventObject.RT:=rType; EventObject.Value:=RequestValue; XMLHttp.onreadystatechange:= IDispatch(EventObject); InitRequest(rType,Url,Username,Password); if rType=GET then SendRequest('') else SendRequest(GetParameters()); result:=true; except EventObject.FreeInstance; EventObject:=nil; end; end; function TXMLRequestAsync.GetParameters():string; var x:integer; begin setlength(result,0); for x:=0 to high(nParamNames) do begin result:=result+nParamNames[x]+'='+ChangeURLChars(nParamValues[x]); if x=high(nParamNames) then break; result:=result+'&'; end; end; procedure TXMLRequestAsync.SendRequest(const rData:string); begin XMLHTTP.send(rData); end; end.