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

  • 相关阅读:
    hdu4587 Two Nodes 求图中删除两个结点剩余的连通分量的数量
    洛谷3388 tarjan割点
    POJ1523 Tarjan求割点以及删除割点之后强连通分量的数量
    POJ1144 tarjan+网络中割点与割边的数量
    POJ1780 欧拉路+手写栈解决爆战问题
    Delphi 窗体函数GetForegroundWindow
    Delphi 窗体函数GetClassName
    Delphi 窗体函数GetDesktopWindow
    Delphi 窗体函数 GetTopWindow、GetNextWindow
    Delphi 调用惯例 register, pascal, cdecl, stdcall, safecall 介绍
  • 原文地址:https://www.cnblogs.com/liubiqu/p/2541231.html
Copyright © 2020-2023  润新知