您的位置:首页 > 大数据 > 人工智能

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

2014-03-19 15:48 288 查看
标题: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转换了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: