Delphi處理Http請求自定義Header


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

 

由於目前后台的接口采用的是Servlet來響應HTTP請求,所有的請求也必須遵循javaee servlet的規范。在Servlet 2.3及以后的版本中,已經默認增加了Filter處理,所以如果要在Servlet中的request對象能夠自動讀取post form的數據要滿足以下條件:

1.request是HTTP/HTTPS request

2.HTTP method是POST。

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

 

在Delphi中有很多實體類可以實現HTTP請求,但比較方便的就是使用THTTPReqResp,比較原始的TIdHTTP類(需要自行管理cookie的值)。

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

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

FHttpReq.OnBeforePost := BeforePost;

通過替換的方式把原來的content-type改為想要的結果:

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;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM