You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 10+下TWebBrowser中XMLHttpRequest POST数据无法发送

问题描述

使用Delphi 11.3或10.4.1开发,通过TWebBrowser组件(变量名AWB)执行JavaScript发送POST请求,代码如下:

AWB.EvaluateJavaScript(
//      'alert( "var3=pmp ap pn q m" );' + #13 + #10 + // 该代码始终正常工作
    '{ let xhr = new XMLHttpRequest();' + #13 + #10 +     
    'xhr.open("POST", "http://127.0.0.1:50001", false);' + #13 + #10 +            
    'xhr.send("var3=pmp ap pn q m");' + #13 + #10 +
    ' }');

其中JS的alert功能正常。

服务器端使用TIdHTTPServer接收请求,DFM配置如下:

object IdHTTPServer1: TIdHTTPServer
  Bindings = <
    item
      IP = '127.0.0.1'
      Port = 50001
    end>
  DefaultPort = 50001
  TerminateWaitTime = 1000
  AutoStartSession = True
  ParseParams = False
  OnCommandGet = IdHTTPServer1CommandGet
end

通过IdHTTP1直接POST到本地服务器可正常接收:

var JSon        : TStringStream;

Json   := TStringStream.Create('Hee ll p', TEncoding.UTF8);
IdHTTP1.Post('http://127.0.0.1:50001', Json);

核心问题:XMLHttpRequest的POST请求在Android 8.1(MIUI 9.6)上正常,但在Android 10(MIUI 12)和Android 12(MIUI 14)上,服务器端的ARequestInfo.PostStream为空,无法获取POST数据。项目基于Embarcadero官方示例:C:\Users\Public\Documents\Embarcadero\Studio\22.0\Samples\Object Pascal\Mobile Snippets\WebBrowser

服务器端处理代码:

procedure TWebBrowserForm.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
  var
    Stream : TStream;
begin
  AResponseInfo.ResponseNo:= 200;
  AResponseInfo.ContentText:= 'OKOK';
  if ARequestInfo.Command = 'POST' then
  begin

    Stream := ARequestInfo.PostStream; // Android 10+下此处为nil
    if assigned(Stream) then
    begin
      FAnswer_Content := ReadStringFromStream(Stream, -1, IndyTextEncoding_UTF8);
    end
  end;

end;
解决方案

1. 补充请求头信息

Android 10+的WebView(TWebBrowser底层基于WebView)对XHR请求的规范要求更严格,未指定Content-Type头时,可能导致请求体被丢弃。修改JavaScript代码,添加Content-Type:

{ let xhr = new XMLHttpRequest();
xhr.open("POST", "http://127.0.0.1:50001", false);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("var3=pmp ap pn q m");
}

对应Delphi代码转义后:

AWB.EvaluateJavaScript(
    '{ let xhr = new XMLHttpRequest();' + #13 + #10 +     
    'xhr.open(&quot;POST&quot;, &quot;http://127.0.0.1:50001&quot;, false);' + #13 + #10 +            
    'xhr.setRequestHeader(&quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;);' + #13 + #10 +
    'xhr.send(&quot;var3=pmp ap pn q m&quot;);' + #13 + #10 +
    ' }');

2. 调整服务器端参数解析配置

当前服务器ParseParams = False,虽然直接读取PostStream理论可行,但Android 10+的请求可能触发Indy的参数解析逻辑异常。建议将ParseParams设为True,同时增加FormParams读取作为备选:

procedure TWebBrowserForm.IdHTTPServer1CommandGet(AContext: TIdContext;
  ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var
  Stream : TStream;
begin
  AResponseInfo.ResponseNo:= 200;
  AResponseInfo.ContentText:= 'OKOK';
  if ARequestInfo.Command = 'POST' then
  begin
    // 优先读取FormParams
    if ARequestInfo.FormParams.Count > 0 then
    begin
      FAnswer_Content := ARequestInfo.FormParams.Text;
    end
    else if Assigned(ARequestInfo.PostStream) then
    begin
      Stream := ARequestInfo.PostStream;
      FAnswer_Content := ReadStringFromStream(Stream, -1, IndyTextEncoding_UTF8);
    end;
  end;
end;

3. 确认应用权限配置

Android 10+对本地网络访问有更严格的限制,确保应用已申请以下权限:

  • INTERNET:允许网络访问
  • ACCESS_NETWORK_STATE:获取网络状态

在Delphi项目中,可通过项目选项 -> Permissions标签直接勾选对应权限,无需手动修改AndroidManifest.xml。

内容的提问来源于stack exchange,提问作者Станислав 000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 09:51:05