【问题标题】:Delphi - idHTTP upload file using TIdMultipartFormDataStreamDelphi - 使用 TIdMultipartFormDataStream 的 idHTTP 上传文件
【发布时间】:2016-11-22 03:38:27
【问题描述】:

我正在尝试使用TIdHTTP 上传文件。问题是当请求被发送到服务器时访问令牌被更改。

我使用的访问令牌是fJNhDM6TlcpeVmD8h3jFuPJS71sxwZB8bZBXajTRB5TNAcRa6PNXfv4J7mPxIvMdMhjy7oKdTLbsRYthpBCCqGVkj4vlojJ4BRBkLAVIBJ1DZAnMZD

API 返回

HTTP/1.1 400 Bad Request OAuth "invalid_token" "Malformed access token fJNhDM6TlcpeVmD8h3jFu=\r\nPJS71sxwZB8bZBXajTRB5TNAcRa6PNXfv4J7mPxIvMdMhjy7oKdTLbsRYthpBCCqGVkj4v=\r\nlojJ4BRBkLAVIBJ1DZAnMZD"

=\r\n 两次添加到我的令牌中。

我的代码是:

function TFoo.Post(const AToken, guID, AMessage, AImageFileName: string): Boolean;
var
  lParam : TIdMultipartFormDataStream;
begin
  Result := False;
  if not FileExists(AImageFileName) then begin
    LastError := 'File not found ' + AImageFileName;
    Exit;
  end;
  ProxyCheck;
  lParam := TIdMultipartFormDataStream.Create;
  try
    lParam.AddFormField('message', AMessage);
    lParam.AddFormField('access_token', AToken);
    lParam.AddFile('source', AImageFileName);
    idHTTP.Request.ContentType := 'application/x-www-form-urlencoded';
    try
      idHTTP.Post( UrlAPI + guID + '/photos', lParam);
      Result := True;
    except;
      LastError := idHTTP.ResponseText + sLineBreak + idHTTP.Response.WWWAuthenticate.Text;
    end;
  finally
    lParam.Free;
  end;
end;   

我在这里错过了什么?

【问题讨论】:

    标签: delphi idhttp


    【解决方案1】:

    默认情况下,AddFormField()TIdFormDataField.ContentTransfer 属性设置为 MIME 的 quoted-printable 格式。这就是额外的=\r\n 的来源。这是 quoted-printable 每 76 个字符插入一个“软”换行符。任何支持quoted-printable 的服务器都会在解码过程中删除“软”换行符。但也许你的服务器没有。

    如果要禁用quoted-printable 行为,可以将ContentTransfer 属性设置为:

    1. 一个空白字符串:

      lParam.AddFormField('access_token', AToken).ContentTransfer := '';
      
    2. '7bit'(因为它不包含任何非ASCII字符):

      lParam.AddFormField('access_token', AToken).ContentTransfer := '7bit';
      
    3. '8bit'binary

      lParam.AddFormField('access_token', AToken).ContentTransfer := '8bit';
      

      lParam.AddFormField('access_token', AToken).ContentTransfer := 'binary';
      

    在这种情况下,我建议#1。

    附带说明,发布TIdMultipartFormDataStream 时不要设置HTTP 内容类型。不仅您使用了错误的媒体类型开头(它应该是multipart/form-data),而且Post()TIdMultipartFormDataStream 版本无论如何都会简单地覆盖它。

    function TFoo.Post(const AToken, guID, AMessage, AImageFileName: string): Boolean;
    var
      lParam : TIdMultipartFormDataStream;
    begin
      Result := False;
      if not FileExists(AImageFileName) then begin
        LastError := 'File not found ' + AImageFileName;
        Exit;
      end;
      ProxyCheck;
      lParam := TIdMultipartFormDataStream.Create;
      try
        lParam.AddFormField('message', AMessage);
        lParam.AddFormField('access_token', AToken).ContentTransfer := '';
        lParam.AddFile('source', AImageFileName);
        try
          idHTTP.Post(UrlAPI + guID + '/photos', lParam);
          Result := True;
        except;
          LastError := idHTTP.ResponseText + sLineBreak + idHTTP.Response.WWWAuthenticate.Text;
        end;
      finally
        lParam.Free;
      end;
    end;   
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多