【问题标题】:idhttp ISO-8859-1 multipart postidhttp ISO-8859-1 多部分帖子
【发布时间】:2012-08-22 07:42:53
【问题描述】:

经过 2 天的尝试猜测正确方法后,我放弃了。 很多关于这个主题的问题,但没有任何帮助。

请告诉我我的错误。

任务:将多部分形式(字符串字段和文件)发送到服务器。 服务器等待 ISO-8859-1 编码。

    http.Request.Host := fHost;
    http.Request.AcceptEncoding := '*';
    http.Request.UserAgent := HTTPUserAgent;
    http.Request.ContentEncoding := 'ISO-8859-1';
//        http.Request.CharSet  := 'ISO-8859-1';
    if HTTPProxyActive then
      http.Request.ProxyConnection := 'close'
    else
      http.Request.Connection := 'close';
    http.Request.ContentType := 'text/plain';

    addr := 'https://'+Host+URL;

    if ValCount>0 then begin
      Stream := TIdMultipartFormDataStream.Create;
      for i:=0 to ValCount-1 do begin
        if Values[i].Name<>'' then
        begin
          field := Stream.AddFormField(Values[i].Name, Values[i].Value, 'ISO-8859-1');
//              field.Charset := 'ISO-8859-1';
//              field.ContentTransfer := '7bit';
        end;
        if Values[i].Filename<>'' then
          Stream.AddFile(Values[i].FileName, Values[i].Value, 'text/plain');
      end;
      resp := TStringStream.Create;
      http.Post(addr, Stream, resp);
      st := resp.DataString;
      resp.Destroy;
      Stream.Destroy;
    end

作为帖子的结果我有???????服务器上的顺序。 当我定义字段或请求的字符集时,服务器上出现错误。

请帮助我或缺少什么信息?

更新:我可以使用 UTF-8 获得结果。但是在服务器中我得到了 UTF-8 值,我需要 ISO-8859-1。

UTF-8 解决方案:

field := Stream.AddFormField(Values[i].Name, Values[i].Value, 'UTF-8');
field.ContentTransfer := '8bit';

【问题讨论】:

    标签: encoding delphi-2010 indy indy10 multipartform-data


    【解决方案1】:

    假设您使用的是最新版本的 Indy 10,那么TIdMultipartFormDataStream 可以很好地与 ISO-8859-1 配合使用。只需指定要指定 UTF-8 的任何位置。您还需要修复 Request.ContentEncoding 分配的错误 - 字符串字符集不是有效的内容编码。这是 HTTP 完全不同的特性。你需要去掉TStringStream,因为它会阻止TIdHTTP为你解码响应字符串数据。

    试试这个:

    if ValCount > 0 then
    begin
      http.Request.AcceptEncoding := '*';
      http.Request.UserAgent := HTTPUserAgent;
      if HTTPProxyActive then
        http.Request.ProxyConnection := 'close'
      else
        http.Request.Connection := 'close';
    
      addr := 'https://'+Host+URL;
    
      Stream := TIdMultipartFormDataStream.Create;
      try
        for i := 0 to ValCount-1 do begin
          if Values[i].Name <> '' then
          begin
            field := Stream.AddFormField(Values[i].Name, Values[i].Value, 'ISO-8859-1');
            field.ContentTransfer := '8bit';
          end;
          if Values[i].FileName <> '' then
            Stream.AddFile(Values[i].Name, Values[i].FileName, 'text/plain');
        end;
        st := http.Post(addr, Stream);
      finally
        Stream.Free;
      end;
    end;
    

    或者:更符合您展示的“解决方案”:

    if ValCount > 0 then
    begin
      http.Request.AcceptEncoding := '*';
      http.Request.UserAgent := HTTPUserAgent;
      if HTTPProxyActive then
        http.Request.ProxyConnection := 'close'
      else
        http.Request.Connection := 'close';
    
      addr := 'https://'+Host+URL;
    
      Stream := TIdMultipartFormDataStream.Create;
      try
        for i := 0 to ValCount-1 do begin
          if Values[i].Name <> '' then
          begin
            field := Stream.AddFormField(Values[i].Name, Values[i].Value, 'ISO-8859-1');
            field.ContentTransfer := '8bit';
            field.FileName := Values[i].FileName;
          end;
        end;
        st := http.Post(addr, Stream);
      finally
        Stream.Free;
      end;
    end;
    

    【讨论】:

    • 雷米,谢谢。但我尝试了提供的方式,我记得有更长的问题 ???.
    • 您使用的是最新版本的 Indy 10 吗?获得'?' 字符的唯一方法是输入数据使用ISO-8859-1 中不存在的非ASCII 字符。您的代码没有处理这种可能性。您的代码完全忽略字符集并使用TEncoding.Default 对字符串数据进行编码(如果您不告诉它使用不同的编码,这就是TStringStream 在内部使用的内容)。而在 Indy 中,它会将字符串数据实际编码为您指定的任何字符集,在本例中为 ISO-8859-1。
    • 非常感谢。我需要非常快速的解决方案,不幸的是花了 3 天时间,我没有时间尝试其他方法。我的客户有工作代码。如果我们将来有问题,那么我会走你的路。再次感谢您的出色图书馆。
    【解决方案2】:

    解决方案

    互联网上有很多解决方案。来自 Remy 的很多解决方案。 但它们都是关于 UTF-8 的。 服务器无法获取 UTF-8 字符串...而且我无法访问服务器端脚本以纠正情况。 所以我在没有 TIdMultipartFormDataStream 类的情况下手动创建我的请求。

    我认为我的解决方案将对下一个解决方案有用。 祝你好运。

        http.Request.ContentType := 'multipart/form-data; boundary=' + FBound;
        if HTTPProxyActive then
          http.Request.ProxyConnection := 'close'
        else
          http.Request.Connection := 'close';
    
        addr := 'http://'+Host+URL;
        resp := TStringStream.Create;
        if ValCount>0 then
        begin
          cont := '';
          for i:=0 to ValCount - 1 do
          begin
            cont := cont + '--' + FBound + #13#10;
            cont := cont + 'Content-Disposition: form-data';
            if Values[i].Filename<>'' then
              cont := cont + '; filename="' + Values[i].Filename + '"';
            if Values[i].Name<>'' then
              cont := cont + '; name="' + Values[i].Name + '"';
            cont := cont + #13#10+#13#10;
            cont := cont + Values[i].Value;
            cont := cont + #13#10;
          end;
          cont := cont + '--' + FBound + '--' + #13#10#13#10;
          http.Request.ContentLength := Length(cont);
          req := TStringStream.Create(cont);
          http.Post(addr, req, resp);
          FreeAndNil(req);
        end
        else
        begin
          http.Get(addr, resp);
        end;
        st := resp.DataString;
        resp.Destroy;
    

    【讨论】:

      猜你喜欢
      • 2015-10-11
      • 2011-06-10
      • 2013-01-19
      • 2012-05-25
      • 1970-01-01
      • 2019-02-21
      • 2013-05-05
      • 2011-12-27
      • 1970-01-01
      相关资源
      最近更新 更多