2016-11-21 1011 views
1

我试图使用TIdHTTP上传文件。问题是访问令牌在请求发送到服务器时发生了变化。使用TIdMultipartFormDataStream的Delphi-idHTTP上传文件

,我使用的访问令牌是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

默认情况下,AddFormField()TIdFormDataField.ContentTransfer属性设置为MIME的quoted-printable格式。这是额外的=\r\n来自何处。这是一个“软”换行符,每76个字符由quoted-printable插入。任何支持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;