Delphi處理Http請求自定義Header

在HTTP請求中,get方法是默認的,但在URL地址長度是有限的,請求方法能傳送的數據也是有限的,通常get方法傳遞的數據不能大於2KB,當get請求方法傳遞的數據長度不能知足需求時,就須要採用另外一種請求方法post,讀取post方法傳遞過來的數據時,須要採用form方法來獲取;post方法提交請求時,地址欄看不到傳送過來的參數數據,更加有利於頁面的安全,因此通常狀況採用post方法傳送頁面數據。post傳送的數據量較大,通常被默認爲不受限制。但理論上,IIS5中最大量爲100KB。java

 

因爲目先後臺的接口採用的是Servlet來響應HTTP請求,全部的請求也必須遵循javaee servlet的規範。在Servlet 2.3及之後的版本中,已經默認增長了Filter處理,因此若是要在Servlet中的request對象可以自動讀取post form的數據要知足如下條件:安全

1.request是HTTP/HTTPS request服務器

2.HTTP method是POST。cookie

3.content type是application/x-www-form-urlencoded。網絡

 

在Delphi中有不少實體類能夠實現HTTP請求,但比較方便的就是使用THTTPReqResp,比較原始的TIdHTTP類(須要自行管理cookie的值)。app

由於THTTPReqResp自動封裝了請求的細節處理,能夠省去不少麻煩,特別是對Cookie的管理,但該對象發送請求的時候Header默認的content-type="text/xml" 因此要修改請求頭的content-type才能夠能夠服務器端接收到post的數據。ide

要實現自定義Header須要在OnBeforePost事件中重定義Header信息post

FHttpReq.OnBeforePost := BeforePost;url

經過替換的方式把原來的content-type改成想要的結果:code

HttpAddRequestHeaders(Data, PChar(csCustomHeader), Length(csCustomHeader), HTTP_ADDREQ_FLAG_REPLACE);

 

詳細的代碼以下:

 

{ -------------------------------------------------------------------------------

過程名: TDataSync.ModPassword

參數: oldPass:原密碼

newPass:新密碼

返回值: true表示成功;false表示失敗,失敗時能夠經過GetLastError得到錯誤信息

------------------------------------------------------------------------------- }

function TDataSync.ModPassword(oldPass, newPass: string): boolean;

var

url, content: string;

begin

result := false;

try

url := Format(URL_AltPass, [FWebSite, oldPass, newPass]);

content := GetResponseContent(url);

result := GetResponseState(content);

except

SetLastError('網絡故障,更改用戶密碼失敗!');

end;

end;

 

procedure TDataSync.BeforePost(const HTTPReqResp: THTTPReqResp; Data: Pointer);

const

csCustomHeader =

'Content-Type: application/x-www-form-urlencoded; charset=UTF-8';

begin

HttpAddRequestHeaders(Data, PChar(csCustomHeader), Length(csCustomHeader),

HTTP_ADDREQ_FLAG_REPLACE);

end;

 

function TDataSync.GetResponseContentPost(url: string;

const DataMsg: String): string;

var

strStream, strSend: TStringStream;

begin

result := '';

strStream := TStringStream.Create('', TEncoding.UTF8);

strSend := TStringStream.Create(DataMsg, TEncoding.UTF8);

try

FHttpReq.url := url;

FHttpReq.OnBeforePost := BeforePost;

FHttpReq.Execute(strSend, strStream);

result := strStream.DataString;

except

SetLastError('無效數據包,可能網絡故障!');

end;

strStream.Free;

strSend.Free;

end;

 

// 重載簡單接口調用

function TDataSync.GetResponseContent(url: string): string;

begin

result := GetResponseContentPost(url, '');

end;

 

function TDataSync.GetResponseState(strResponse: string): boolean;

var

code: string;

jo: ISuperObject;

begin

result := false;

if strResponse = '' then

begin

SetLastError('服務端無響應當前服務請求!');

exit;

end;

 

jo := TSuperObject.ParseString(PWideChar(strResponse), false);

if jo = nil then

exit;

 

if jo['flag'] = nil then

begin

SetLastError('未知的服務響應!');

exit;

end;

code := jo['flag'].AsString;

result := (code = QUERY_SUCC) or (code = OP_SUCC);

if jo['info'] <> nil then

SetLastError(jo['info'].AsString)

else

begin

if code = 'EMPLOYEECODE_EXIST' then

SetLastError('工號已存在')

else if code = 'EXCEED_MORE_THAN_LIMIT' then

SetLastError('超過公司的總人數')

else

SetLastError(code);

end;

end;

 

{ ------------------------------------------------------------------------------ }

constructor TDataSync.Create(AOwner: TSWObject; url, dicURL: string);

begin

inherited Create(AOwner);

FWebSite := url;

FDicSite := dicURL;

 

FHttpReq := THTTPReqResp.Create(AOwner);

FHttpReq.UseUTF8InHeader := true;

end;

 

destructor TDataSync.Destroy();

begin

FHttpReq.Free;

inherited;

end;

相關文章
相關標籤/搜索