Delphi - 使用TIdMultipartFormDataStream的idHTTP上传文件

时间:2016-11-21 00:14:56

标签: delphi idhttp

我尝试使用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;   

我在这里缺少什么?

1 个答案:

答案 0 :(得分:1)

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

如果要禁用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';
    
  4. 在这种情况下,我建议#1。

    另请注意,发布TIdMultipartFormDataStream时请勿设置HTTP内容类型。您不仅开始使用错误的媒体类型(而应该是multipart/form-data),但TIdMultipartFormDataStream Post()版本的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; 只会覆盖它。

    The reply address '...' does not match the reply addresses configured for the application