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

如何通过Indy组件的TIdHTTP向APNS发送推送通知?

问题根因

  • 苹果APNs新接口强制要求使用HTTP/2协议,你当前使用的Indy TIdHTTP组件原生仅支持HTTP/1.1,手动添加的:method/:scheme/:path等HTTP/2伪头在HTTP/1.1协议下完全无效,这是功能失效的核心原因。
  • 你的现有代码还存在多个低级错误,进一步导致请求无法正常发送:
    • SslIOHandlerHTTP.PassThrough := true会直接跳过SSL握手流程,配置的PEM证书完全不会生效
    • Post方法仅传入域名,未拼接完整的设备路径,且手动配置的:path伪头不会被TIdHTTP识别使用
    • JSON字符串使用了HTML转义符"而非原生双引号,请求体格式错误
    • 所有创建的组件、流对象未手动释放,存在内存泄漏

修复方案

如果你的Delphi版本在10.4及以上,建议直接使用自带的TNetHTTPClient组件,原生支持HTTP/2协议,适配APNs新要求的代码示例如下:

uses
  System.Net.HttpClient, System.Net.HttpClientComponent, System.SysUtils, System.Classes, System.JSON;

procedure TForm5.BtnPushClick(Sender: TObject);
var
  vHTTP: TNetHTTPClient;
  vRequest: IHTTPRequest;
  vResponse: IHTTPResponse;
  vJsonToSend: TStringStream;
  vCertFileName: string;
  vDeviceToken: string;
begin
  vCertFileName := 'apns-dist.pem';
  vDeviceToken := '111890052839d3ed4f596c94712329e20812464afe30ebd28487c4e65986c6f0';
  vHTTP := TNetHTTPClient.Create(nil);
  vJsonToSend := TStringStream.Create('{ "aps" : { "alert" : "Hello" } }', TEncoding.UTF8);
  try
    // 配置SSL证书
    vHTTP.SSLOptions.CertFile := vCertFileName;
    vHTTP.SSLOptions.KeyFile := vCertFileName;
    vHTTP.SSLOptions.TLSVersions := [TLSVersion.TLSv12];
    
    // 构建请求
    vRequest := vHTTP.CreateRequest('POST', 'https://api.push.apple.com/3/device/' + vDeviceToken);
    vRequest.Header.Set('apns-id', 'eabeae54-14a8-11e5-b60b-1697f925ec7b');
    vRequest.Header.Set('apns-push-type', 'alert');
    vRequest.Header.Set('apns-expiration', '0');
    vRequest.Header.Set('apns-priority', '10');
    vRequest.Header.Set('apns-topic', 'com.TS.JACK');
    vRequest.ContentType := 'application/json';
    vRequest.SourceStream := vJsonToSend;
    
    // 发送请求(自动使用HTTP/2协议)
    vResponse := vRequest.Execute;
    Memo1.Lines.Add('响应码:' + IntToStr(vResponse.StatusCode));
    Memo1.Lines.Add('响应内容:' + vResponse.ContentAsString);
  except
    on E: Exception do
    begin
      Memo1.Lines.Add('错误:' + E.Message);
    end;
  end;
  vJsonToSend.Free;
  vHTTP.Free;
end;

如果你必须继续使用Indy组件,需要引入第三方的Indy HTTP/2扩展实现,或者直接使用TIdTCPClient手动封装HTTP/2帧、ALPN协商逻辑,开发成本较高,不推荐。

内容的提问来源于stack exchange,提问作者Johny

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:39:03