在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
技术交流,DH讲解. 前段时间,和群里面的朋友讨论提交包的时候,结果发现Indy被大家狂批,哈哈,后来有人推荐用WinHttp,查看了下MSDN,WinHttp主要是靠system32目录下面的WinHttp.dll这个文件,而它又有2种用法,一个是直接API,复杂些,但是功能强大,另外一个就是直接使用WinHttpRequest这个ActiveX. 为了使用方便,对WinHttpRequest进行了简单封装,但是感觉不完善,有空补足.还有好多方法没有封装进来,但是留了一个属性property Http:OleVariant read FHttp write FHttp; 这样大家可以直接调用WinHttpRequest.来看看代码:(直接下载) unit utWinHttp; interface uses SysUtils,Classes,Windows; const request_headers:array[0..14] of string = ( 'Accept','Accept-Encoding','Accept-Language','Cache-Control', 'CharSet','Connection','Content-Encoding','Content-Language', 'Content-Type','Date','Expires','From', 'Referer','UserAgent','Cookie' ); const WinHttpRequestOption_UserAgentString = $00000000; WinHttpRequestOption_URL = $00000001; WinHttpRequestOption_URLCodePage = $00000002; WinHttpRequestOption_EscapePercentInURL = $00000003; WinHttpRequestOption_SslErrorIgnoreFlags = $00000004; WinHttpRequestOption_SelectCertificate = $00000005; WinHttpRequestOption_EnableRedirects = $00000006; WinHttpRequestOption_UrlEscapeDisable = $00000007; WinHttpRequestOption_UrlEscapeDisableQuery = $00000008; WinHttpRequestOption_SecureProtocols = $00000009; WinHttpRequestOption_EnableTracing = $0000000A; WinHttpRequestOption_RevertImpersonationOverSsl = $0000000B; WinHttpRequestOption_EnableHttpsToHttpRedirects = $0000000C; WinHttpRequestOption_EnablePassportAuthentication = $0000000D; WinHttpRequestOption_MaxAutomaticRedirects = $0000000E; WinHttpRequestOption_MaxResponseHeaderSize = $0000000F; WinHttpRequestOption_MaxResponseDrainSize = $00000010; WinHttpRequestOption_EnableHttp1_1 = $00000011; WinHttpRequestOption_EnableCertificateRevocationCheck = $00000012; AutoLogonPolicy_Always = $00000000; AutoLogonPolicy_OnlyIfBypassProxy = $00000001; AutoLogonPolicy_Never = $00000002; SslErrorFlag_UnknownCA = $00000100; SslErrorFlag_CertWrongUsage = $00000200; SslErrorFlag_CertCNInvalid = $00001000; SslErrorFlag_CertDateInvalid = $00002000; SslErrorFlag_Ignore_All = $00003300; SecureProtocol_SSL2 = $00000008; SecureProtocol_SSL3 = $00000020; SecureProtocol_TLS1 = $00000080; SecureProtocol_ALL = $000000A8; const IStream_GUID:TGUID = '{0000000C-0000-0000-C000-000000000046}'; type TCustomWinHttp = class; //请求信息类 TRequest = class(TPersistent) private FAccept,FAcceptEncoding,FAcceptLanguage:string; FCacheControl,FCharSet,FConnection:string; FContentEncoding,FContentLanguage,FContentType:string; FDate,FExpires,FFrom:string; FReferer,FUserAgent:string; FCookie:string; FCustomHeader:TStringList; public constructor Create; destructor Destroy; override; published property Accept:string read FAccept write FAccept; property AcceptEncoding:string read FAcceptEncoding write FAcceptEncoding; property AcceptLanguage:string read FAcceptLanguage write FAcceptLanguage; property CacheControl:string read FCacheControl write FCacheControl; property CharSet:string read FCharSet write FCharSet; property Connection:string read FConnection write FConnection; property ContentEncoding:string read FContentEncoding write FContentEncoding; property ContentLanguage:string read FContentLanguage write FContentLanguage; property ContentType:string read FContentType write FContentType; property Date:string read FDate write FDate; property Expires:string read FExpires write FExpires; property From:string read FFrom write FFrom; property Referer:string read FReferer write FReferer; property UserAgent:string read FUserAgent write FUserAgent; property Cookie:string read FCookie write FCookie; property CustomHeader:TStringList read FCustomHeader write FCustomHeader; end; //返回信息类 TResponse = class(TPersistent) private FOwner:TCustomWinHttp; FHeaderList:TStringList; procedure Check; function Get_Header(const header_name:string):string; function Get_Status:Integer; function Get_StatusText:string; function Get_ResponseBody:string; function Get_HeadersText:string; public constructor Create(http:TCustomWinHttp); destructor Destroy; override; property Header[const Name:string]:string read Get_Header; property Status:Integer read Get_Status; property StatusText:string read Get_StatusText; property ResponseBody:string read Get_ResponseBody; property HeadersText:string read Get_HeadersText; end; TCustomWinHttp = class(TComponent) private FCreated:Boolean; FHttp:OleVariant; FRequest:TRequest; FResponse:TResponse; FRequestTime:Integer; FOnRequestTimeOut:TNotifyEvent; procedure SetRequestHeaders; procedure Set_Option(idx:Integer;value:OleVariant); function Get_Option(idx:Integer):OleVariant; procedure Set_Redirects(B:Boolean); function Get_Redirects:Boolean; procedure Set_MaxRedirects(N:Integer); function Get_MaxRedirects:Integer; public procedure Abort; procedure ClearRequestHeaders; function Get(const URL:string):string;overload; procedure Get(Const URL:string;res:TStream);overload; function Post(const URL:string;Req:TStream):string;overload; function Post(const URL,Req:string):string;overload; procedure Post(const URL:string;Req,Res:TStream);overload; procedure Post(const URL,Req:string;Res:TStream);overload; constructor Create(AOwner: TComponent); override; destructor Destroy; override; property Http:OleVariant read FHttp write FHttp; property EnableRedirects:Boolean read Get_Redirects write Set_Redirects; property MaxRedirects:Integer read Get_MaxRedirects write Set_MaxRedirects; property Request:TRequest read FRequest write FRequest; property RequestTime:Integer read FRequestTime write FRequestTime; property OnRequestTimeOut:TNotifyEvent read FOnRequestTimeOut write FOnRequestTimeOut; property Response:TResponse read FResponse write FResponse; property Options[idx:Integer]:OleVariant read Get_Option write Set_Option; end; TWinHttp = class(TCustomWinHttp) published property MaxRedirects; property EnableRedirects; property Request; property Response; property RequestTime; property OnRequestTimeOut; end; implementation uses ComObj,AxCtrls,ActiveX,Variants; { TResponse } procedure TResponse.Check; begin if FHeaderList.Count = 0 then FHeaderList.Text:=FOwner.FHttp.GetAllResponseHeaders; end; constructor TResponse.Create(http:TCustomWinHttp); begin FOwner:=http; FHeaderList:=TStringList.Create; FHeaderList.NameValueSeparator:=':'; end; destructor TResponse.Destroy; begin FHeaderList.Free; inherited; end; function TResponse.Get_Header(const header_name: string): string; begin Check; Result:=FHeaderList.Values[header_name]; end; function TResponse.Get_HeadersText: string; begin Check; Result:=FHeaderList.Text; end; function TResponse.Get_ResponseBody: string; begin Result:=FOwner.Http.ResponseBody; end; function TResponse.Get_Status: Integer; begin Result:=FOwner.Http.Status; end; function TResponse.Get_StatusText: string; begin Result:=FOwner.Http.StatusText; end; { TRequest } constructor TRequest.Create; begin inherited; FCustomHeader:=TStringList.Create; end; destructor TRequest.Destroy; begin FCustomHeader.Free; inherited; end; { TCustomWinHttp } procedure TCustomWinHttp.Abort; begin if FCreated then FHttp.Abort(); end; procedure TCustomWinHttp.ClearRequestHeaders; var I,base: Integer; begin base := Integer(FRequest); for I := 0 to 14 do PDWORD(base + 4 * (I+1))^:=0; FRequest.CustomHeader.Clear; end; constructor TCustomWinHttp.Create(AOwner: TComponent); begin inherited; FRequest:=TRequest.Create; FRequest.FCustomHeader.NameValueSeparator:=':'; FResponse:=TResponse.Create(Self); try FCreated:=False; FHttp:=CreateOleObject('WinHttp.WinHttpRequest.5.1'); FCreated:=True; except raise Exception.Create('创建WinHttp失败'); end; FRequestTime:=4000; end; destructor TCustomWinHttp.Destroy; begin Abort; FHttp:=0; FResponse.Free; FRequest.Free; inherited; end; function TCustomWinHttp.Get(const URL: string): string; var ss:TStringStream; begin Result:=''; ss:=TStringStream.Create; try Get(URL,SS); Result:=ss.DataString; finally ss.Free; end; end; procedure TCustomWinHttp.Get(const URL: string; res: TStream); var iu:IUnknown; os:TOlestream; s:IStream; p:OleVariant; w:Word; begin Assert(res<>Nil); if Not FCreated then Exit; //清除已经有的header FResponse.FHeaderList.Clear; //请求 try FHttp.Open('GET',URL,False); SetRequestHeaders; FHttp.Send(varEmpty); if Not FHttp.WaitForResponse(FRequestTime) then begin FHttp.Abort; if Assigned(FOnRequestTimeOut) then FOnRequestTimeOut(Self); Exit; end; P:=FHttp.ResponseStream ; W:=VarType(P); if w = varUnknown then begin iu:=IUnknown(P); iu.QueryInterface(IStream_GUID,s); end; if s=nil then Exit; res.Position:=0; os:=TOleStream.Create(s); try os.Position:=0; res.CopyFrom(os,os.Size) finally os.Free end; except end; end; function TCustomWinHttp.Get_MaxRedirects: Integer; begin Result:=Get_Option(WinHttpRequestOption_MaxAutomaticRedirects) ; end; function TCustomWinHttp.Get_Option(idx: Integer): OleVariant; begin Result:=FHttp.Option[idx]; end; function TCustomWinHttp.Get_Redirects: Boolean; begin Result:=FHttp.Option[WinHttpRequestOption_EnableRedirects]; end; function TCustomWinHttp.Post(const URL, Req: string): string; var ss:TStringStream; begin Result:=''; SS:=TStringStream.Create; try Post(URL,Req,SS); Result:=ss.DataString; finally ss.Free; end; end; function TCustomWinHttp.Post(const URL: string; Req: TStream): string; var ss:TStringStream; S:string; begin Assert(Req<>nil); ss:=TStringStream.Create; try Req.Position:=0; ss.CopyFrom(Req,Req.Size); S:=ss.DataString; ss.Clear; Post(URL,S,ss); Result:=ss.DataString; finally ss.Free; end; end; procedure TCustomWinHttp.Post(const URL: string; Req, Res: TStream); var ss:TStringStream; S:string; begin Assert(Req<>nil); ss:=TStringStream.Create; try Req.Position:=0; ss.CopyFrom(Req,Req.Size); S:=ss.DataString; Post(URL,s,Res) finally ss.Free; end; end; procedure TCustomWinHttp.SetRequestHeaders; var I,dx,base: Integer; S:string; begin base:=Integer(FRequest); for I := 0 to 14 do begin dx:=base + 4 * (I + 1); s:=PString(dx)^; if s<>'' then FHttp.SetRequestHeader(request_headers[I],S); end; for I := 0 to FRequest.CustomHeader.Count - 1 do FHttp.SetRequestHeader(FRequest.CustomHeader.Names[I], FRequest.CustomHeader.ValueFromIndex[I] ); end; procedure TCustomWinHttp.Set_MaxRedirects(N: Integer); begin Set_Option(WinHttpRequestOption_MaxAutomaticRedirects,N); end; procedure TCustomWinHttp.Set_Option(idx: Integer; value: OleVariant); begin FHttp.Option[idx]:=value; end; procedure TCustomWinHttp.Set_Redirects(B: Boolean); begin Set_Option(WinHttpRequestOption_EnableRedirects,B); end; procedure TCustomWinHttp.Post(const URL, Req: string; Res: TStream); var s:IStream; os:TOleStream; p:OleVariant; begin Assert(Res<>Nil); if Not FCreated then Exit; FResponse.FHeaderList.Clear; try FHttp.Open('POST',URL,False); SetRequestHeaders; FHttp.SetRequestHeader('Content-Length',IntToStr(Length(Req))); FHttp.Send(Req); if Not FHttp.WaitForResponse(FRequestTime) then begin FHttp.Abort; if Assigned(FOnRequestTimeOut) then FOnRequestTimeOut(Self); Exit; end; P:=FHttp.ResponseStream; if VarType(P) = varUnknown then IUnknown(P).QueryInterface(IStream_GUID,S); if s=nil then Exit; os:=TOleStream.Create(s); try Res.Position:=0; os.Position:=0; Res.CopyFrom(os,os.Size); finally os.Free; end; except end; end; end.
type TForm3 = class(TForm) btn1: TButton; procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure btn1Click(Sender: TObject); private { Private declarations } Http:TWinHttp; public { Public declarations } end; var Form3: TForm3; implementation {$R *.dfm} procedure TForm3.btn1Click(Sender: TObject); var s:string; begin //清空之前的header Http.ClearRequestHeaders; //设置自己的header ,两种方法都可以 //POST时候这个必须设置成这样 Http.Request.ContentType:='application/x-www-form-urlencoded'; // Http.Request.CustomHeader.Add('Content-Type: application/x-www-form-urlencoded'); S:=Http.Post('http://www.renren.com/PLogin.do', '[email protected]&password=密码&origURL=http%3A%2F%2Fwww.renren.com%2FHome.do&domain=renren.com'); //html代码 ShowMessage(S); //返回的header ShowMessage(Http.Response.HeadersText); //状态 ShowMessageFmt('Code:%D,Text:%S', [Http.Response.Status,Http.Response.StatusText] ); end; procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction); begin Http.Free; end; procedure TForm3.FormCreate(Sender: TObject); begin Http:=TWinHttp.Create(Self); //禁止转向 Http.EnableRedirects:=False; end; 再来个下载文件的例子: procedure TForm3.btn2Click(Sender: TObject); var S:TFileStream; begin s:=TFileStream.Create('C:\11.rar',fmCreate); Http.Get('https://files.cnblogs.com/huangjacky/Delphi.Distiller.v1.83.rar',s); s.Free; end;
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论