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

使用Indy TIdHttp.Put调用MS Graph API的Content-Range头异常问题

问题原因和解决方法

核心问题原因

  • 首先TIdHTTP的Ranges属性是用于GET请求时向服务器请求部分内容的,会生成Range请求头,不会在PUT请求中自动生成Content-Range头,所以用这个属性必然会报缺少Content-Range的错误。
  • 直接往CustomHeaders里加Content-Range报错的原因有两个:
    1. 你的流处理逻辑错误:你把文件内容读取后用{}包裹,实际传输的内容长度和你在Content-Range、Content-Length里声明的长度完全不匹配,Graph API校验时发现范围和实际传输字节数不一致,就会报头无效。
    2. Indy会自动处理部分标准HTTP头,你手动加在CustomHeaders里的Content-Range可能会被Indy内部逻辑覆盖或者修改,导致最终发出的头格式不符合要求。

适配修改方案

Indy的PUT请求是符合HTTP标准的,只需要调整使用方式即可适配该场景,修改如下:

  1. 修正流处理逻辑:上传会话的PUT请求需要传输原始的二进制文件内容,不需要额外加JSON包装,直接用TFileStream读取文件即可。
  2. 不要使用Ranges属性,也不要手动往CustomHeaders里加Content-Range,使用Indy内置的请求参数配置即可:
sUploadSession := jsnUSession.Get('uploadUrl').JsonValue.Value;
Form1.htp2.ProtocolVersion := pv1_1; // 必须用HTTP 1.1协议才支持请求端发送Content-Range头
Form1.htp2.Request.ContentType := 'application/octet-stream';
// 配置Content-Range参数
Form1.htp2.Request.ContentRangeStart := 0;
Form1.htp2.Request.ContentRangeEnd := iSize - 1;
Form1.htp2.Request.ContentRangeInstanceLength := iSize;
Form1.htp2.Request.ContentLength := iSize;

fs := TFileStream.Create(sFile, fmOpenRead or fmShareDenyWrite);
try
  try
    Form1.htp2.Put(sUploadSession, fs);
  except
    on E: EIdHTTPProtocolException do
      Form1.RichEdit1.Lines.Add(E.Message + #13#10 + E.ErrorMessage);
  end;
finally
  fs.Free;
end;
  1. 如果是分片上传的场景,只需要对应修改ContentRangeStart、ContentRangeEnd的值为当前分片的字节范围,同时调整ContentLength为当前分片的大小即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:24:02