http://blog.csdn.net/jrq/article/details/4211075(URL参数中文乱码)

标题:Delphi7 WebBrowser + Struts2 Action
作者:JRQ

正文:
使用Delphi7 WebBrowser客户端调用服务器Struts2 Action,并向服务端传递相关参数。
算是针对异构系统做简单集成的一个测试。
简要记之。

一、客户端WebBrowser以HTTP POST方式调用Action并传递参数
客户端Post方法一:
procedure WebNavigate1(sURL, sPostData: String; var wbWebBrowser: TWebBrowser);
var
  vWebAddr, vPostData, vFlags, vFrame, vHeaders: OleVariant;
  i: Integer;
begin
  if Length(sPostData)> 0 then
  begin
    //头信息
    vHeaders:= 'Content-Type:application/x-www-form-urlencoded'+ #10#13#0;  
    //创建二进制参数
    vPostData:= VarArrayCreate([0, Length(sPostData)], varByte);
    for i := 0 to Length(sPostData)-1 do
      begin
        vPostData[i]:= Ord(sPostData[i+1]);
      end;
    //结束字符
    vPostData[Length(sPostData)]:= 0;
    //Set the type of Variant
    //TVarData(vPostData).vType:= varArray; //注释此句。否则类型错误。
  end;
  vWebAddr:= sURL;
  wbWebBrowser.Navigate2(vWebAddr,vFlags,vFrame, vPostData, vHeaders);
  //wbWebBrowser.Navigate(vWebAddr, EmptyParam, EmptyParam, vPostData, vHeaders);
end;

客户端Post方法二:
procedure WebNavigate2(sURL, sPostData: String; var wbWebBrowser: TWebBrowser);
var  PostData,Headers: OleVariant;
     i: Integer;
begin
  //创建字节方式的可变变量数组,并将字符串转换之。
  PostData := VarArrayCreate([0, Length(sPostData) - 1], varByte);
  for i := 1 to Length(sPostData) do
     begin
       PostData[i-1] := Ord(sPostData[i]);
     end;
  //头类型
  Headers := 'Content-Type: application/x-www-form-urlencoded' + #10#13;
  //提交
  wbWebBrowser.Navigate(sURL, EmptyParam, EmptyParam, PostData, Headers);
end;
 
客户端WebBrowser调用方法:
uses HttpApp;
var aURL, aPostData: String;
begin
   //Post方法一
   aURL:='http://127.0.0.1:8088/test/loginAction.action' ;
   aPostData:='UserCode=abc&PassWord=abc';
   //aPostData:='UserCode='+HTTPEncode('用户名')+'&PassWord=abc';
   WebNavigate1(aURL,aPostData,WebBrowser1);
   //Post方法二
   aURL:= 'http://127.0.0.1:8088/test/testAction.action';
   aPostData := 'ParaCode='+HTTPEncode('测试')+'&ParaNumb=123';
   WebNavigate2(aURL,aPostData,WebBrowser1);
end;
 
服务器Action得到参数:
   String pUserCode = request.getParameter("UserCode").toString();
   String pPassWord = request.getParameter("PassWord").toString();
   String pParaCode = request.getParameter("ParaCode").toString();
   String pParaNumb = request.getParameter("ParaNumb").toString();

说明:
TWebBrowser有多个重载方法Navigate(),在此使用的Navigate()方法原型如下:
procedure TWebBrowser.Navigate(const URL: WideString; var Flags: OleVariant; 
                               var TargetFrameName: OleVariant; var PostData: OleVariant; 
                               var Headers: OleVariant);
begin
  DefaultInterface.Navigate(URL, Flags, TargetFrameName, PostData, Headers);
end;

关于Navigate(),帮助中有如下说明:
-----------------------
Use Navigate to locate and download a specific resource. 
Navigate can send an HTTP message to a specified URL and display the results or simply display the results of a specified file.
PostData contains the data sent to the server when using Navigate to generate an HTTP POST message. 
If PostData is NULL, Navigate generates an HTTP GET message. 
PostData is ignored if URL does not specify an HTTP URL.
-----------------------

如果Navigate()方法使用了PostData参数,则是HTTP POST方式的。如果没有PostData参数,则是HTTP GET方式。

Post方式传递的参数在客户端需要做二进制编码。并设置了Http的头信息。

另外,如果PostData中传递的是中文参数,客户端则需要用uses HttpApp单元,使用HTTPEncode()对中文参数编码,然后再做二进制编码。
     

客户端可以在WebBrowser的BeforeNavigate2()事件中捕获Post的参数,如下所示:

procedure TForm1.WebBrowser1BeforeNavigate2(Sender: TObject;
  const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
  Headers: OleVariant; var Cancel: WordBool);
var
  i, nLen: Integer;
  vPostData: OleVariant;
  szData: string;
begin
  //解开PostData参数
  vPostData := PostData;
  if VarIsArray(vPostData, True) then
     begin
       nLen := VarArrayHighBound(vPostData, 1) - VarArrayLowBound(vPostData, 1) + 1;
       SetLength(szData, nLen);
       for i := 0 to nLen - 1 do
          begin
            szData[i + 1] := Chr(Byte(vPostData[VarArrayLowBound(vPostData, 1) + i]));
          end;
       Application.MessageBox(PChar('PostData is : '+ szData),'测试');
     end; 
end;
 
二、客户端WebBrowser以HTTP Get方式调用Action并传递参数
   
客户端WebBrowser以GET方式发送请求:
uses HttpApp;
var aURL:String;
begin
   aURL:= 'http://127.0.0.1:8088/test/loginAction.action?UserCode=abc&PassWord=abc';
   WebBrowser1.Navigate(aURL);
   aURL:= 'http://127.0.0.1:8088/test/testAction.action?ParaCode='+HTTPEncode('测试')+'&ParaNumb=123';
   WebBrowser1.Navigate(aURL);
end;

服务器Action得到参数:
   String pUserCode = request.getParameter("UserCode").toString();
   String pPassWord = request.getParameter("PassWord").toString();
   String pParaCode = new String(request.getParameter("ParaCode").getBytes("ISO8859_1")); //中文参数编码转换
   String pParaNumb = request.getParameter("ParaNumb").toString();

说明:
客户端的WebBrowser的方法Navigate()只使用了一个参数:URL。该URL中包含了向服务器Action提交的参数。
Navigate()方法中没有使用PostData参数,使用的是HTTP GET方式请求。

此处客户端WebBrowser使用的Navigate()方法原型如下:
procedure TWebBrowser.Navigate(const URL: WideString);
begin
  DefaultInterface.Navigate(URL, EmptyParam, EmptyParam, EmptyParam, EmptyParam);
end;

如果URL中包含中文参数,则需要用HTTPEncode()函数对中文参数编码。
同时,服务器Action中需要对该参数做编码转换。

三、一点想法
1.关于安全性:
针对此案例,使用POST比GET方式更为安全。因为POST方式不会在URL中暴露所传递的参数内容。

2.关于系统集成:
针对此案例,可以应用到多个异构系统的集成中,包括单点登录的实现、远程桌面集成访问等等。 ^_^

PS:
use HTTPAPP;
//服务器端接收UTF-8的格式  | 传递中文
HttpEncode(UTF8Encode('中文'))
如果是在XE7下则不需要UTF8Encode转换了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值