在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;