如何使用TW3HttpRequest发送POST数据

时间:2014-02-05 15:51:16

标签: smart-mobile-studio

所以我开始玩短信,我试图制作一个程序(标签和按钮)来点击带有帖子请求的网站并显示结果。

我对提示/警告/错误没有任何问题,一切对我来说都很好。以下代码是对几个现有示例的修改。

procedure TForm1.ExecuteCmd;
var
  whttp : TW3HttpRequest;
  wParams : string;
begin
  wHttp := TW3HttpRequest.Create;
  try

    whttp.OnDataReady := lambda (Sender)
      if (w3Label1.caption = '') then
        w3Label1.caption := wHttp.ResponseText;
    end;

    whttp.OnReadyStateChange := lambda (Sender)
      if (wHttp.ReadyState = 4) and (wHttp.Status = 200) then
      begin
        if (w3Label1.caption = '') then
          w3Label1.caption := wHttp.ResponseText;
      end;
    end;

    wParams := 'cmd=TestID1';
    whttp.open('POST','http://www.server1.com/executecmd.php');
    whttp.RequestHeaders['Content-type'] := 'application/x-www-form-urlencoded';
    whttp.Send(wParams);
  finally
    wHttp.free;
  end;
end;

procedure TForm1.W3Button1Click(Sender: TObject);
begin
  ExecuteCmd;
end;

问题是这样,当我实际点击按钮时,我收到以下错误消息: 未捕获的TypeError:无法读取null [line#6277]

的属性'readyState'

错误在自动生成的代码中,似乎与我专门编写的内容无关。如果我从代码中取出所有对ReadyState的引用,我仍然会收到错误。

我错过了什么?我觉得它与Lambda函数有关。

1 个答案:

答案 0 :(得分:1)

您的问题是您希望whttp.Send阻止。 Send,因为它的JavaScript等价物,是异步的。在POST甚至可以执行之前,whttp对象被释放(在finally块中)。当调用回调(OnReadyStateChanged)时,whttp已经被释放(现在为空),然后您尝试在该被释放(null)对象上调用ReadyState

混淆的另一个原因是Delphi for Windows / OS X中的object.Free会破坏对象,而在Smart中它只会将object引用设置为nil并将破坏留给JavaScript的垃圾采集。这就是为什么whttpFree之后仍然存在以及为什么OnReadyStateChanged被调用的原因。

这很好用:

uses 
  W3System, W3Graphics, W3Components, W3Forms, W3Fonts, W3Borders, W3Application,
  W3Button, W3Inet, W3Memo;

type
  TForm1=class(TW3form)
    procedure W3Button1Click(Sender: TObject);
  private
    {$I 'Form1:intf'}
    whttp: TW3HttpRequest;
  protected
    procedure InitializeForm; override;
    procedure InitializeObject; override;
    procedure Resize; override;
  end;

implementation

{ TForm1}

procedure TForm1.W3Button1Click(Sender: TObject);
var
  wParams: string;
begin
  whttp := TW3HttpRequest.Create;

  whttp.OnReadyStateChange := lambda (Sender)
    if (whttp.ReadyState = 4) and (wHttp.Status = 200) then
    begin
      W3Memo1.Text := wHttp.ResponseText;
      whttp.OnReadyStateChange := nil;
      whttp := nil;
    end;
  end;

  wParams := 'cmd=TestID1';
  whttp.open('POST','http://httpbin.org/post');
  whttp.RequestHeaders['Content-type'] := 'application/x-www-form-urlencoded';
  whttp.Send(wParams);
end;