IdHTTP如何发送原始正文 [英] IdHTTP how to send raw body

查看:155
本文介绍了IdHTTP如何发送原始正文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何使用IdHTTP作为以下PostMan dos来发送消息:

How i can use IdHTTP to send message as PostMan dos below:

我的第一次尝试如下:

function TIdFoo.SendIM(const AID, AMessage: string): Boolean;
const
  _URL = 'https://URL.com/SendMessage';
var
  Params   : TStringStream;
  Response : string;
  LMsg     : string;
begin
  Result := False;
  LMsg := '-----------------------------13932'+
          'Content-Type: application/json; charset=utf-8'+
          'Content-Description: message'+ sLineBreak+          '{"message":{"Type":1,"body":"'+AMessage+'"},"to":["'+AID+'"]}'+
          '-----------------------------13932--;'+sLineBreak;
  Params := TStringStream.Create(LMsg, TEncoding.UTF8);
  try
    IdHTTP.Request.CustomHeaders.AddValue('authorization', 'Bearer ' + FToken);
    IdHTTP.Request.CustomHeaders.AddValue('Origin', 'https://www.URL.com');
    IdHTTP.Request.UserAgent      := 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36';
    IdHTTP.Request.Accept         := '*/*';
    IdHTTP.Request.Referer        := 'https://www.URL.com/en-us/';
    IdHTTP.Request.Host           := 'URL.com';
    IdHTTP.Request.AcceptEncoding := 'gzip, deflate, br';
    IdHTTP.Request.AcceptLanguage := 'Accept-Language';
    IdHTTP.Request.ContentType    := 'multipart/mixed; boundary="---------------------------13932"';
    Params.Position               := 0;
    try
      Response := IdHTTP.Post(_URL, Params);
      Result := True;
    except
      on E: Exception do
        Writeln('Error on Send Message request: '#13#10, e.Message);
    end;
    Writeln(IdHTTP.Request.RawHeaders.Text);
  finally
    Params.Free;
  end;
end;

我以这种方式尝试的第二次尝试

The second attempt i try it this way

function TIdFoo.SendIM(const AID, AMessage: string): Boolean;
const
  _URL = 'https://URL.com/SendMessage';
var
  Params   : TStringStream;
  Response : string;
  LMsg     : string;
begin
  Result := False;
  LMsg := '{"message":{"Type":1,"body":"'+AMessage+'"},"to":["'+AID+'"]}';
  Params := TStringStream.Create(LMsg, TEncoding.UTF8);
  try
    IdHTTP.Request.CustomHeaders.AddValue('authorization', 'Bearer ' + FToken);
    IdHTTP.Request.CustomHeaders.AddValue('Origin', 'https://www.URL.com');
    IdHTTP.Request.CustomHeaders.AddValue('Content-Description', 'message'); // I addedd this as on PostMan Body
    IdHTTP.Request.UserAgent      := 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36';
    IdHTTP.Request.Accept         := '*/*';
    IdHTTP.Request.Referer        := 'https://www.URL.com/en-us/';
    IdHTTP.Request.Host           := 'URL.com';
    IdHTTP.Request.AcceptEncoding := 'gzip, deflate, br';
    IdHTTP.Request.AcceptLanguage := 'Accept-Language';
    IdHTTP.Request.ContentType    := 'application/json; charset=utf-8'; // I alos changed this as it shown on PostMan body
    Params.Position               := 0;
    try
      Response := IdHTTP.Post(_URL, Params);
      Result := True;
    except
      on E: Exception do
        Writeln('Error on Send Message request: '#13#10, e.Message);
    end;
    Writeln(IdHTTP.Request.RawHeaders.Text);
  finally
    Params.Free;
  end;
end;

两次尝试都给出HTTP/1.1 400 Bad Request.

有什么建议可以告诉我我做错了什么吗?

Can any advice my what i', doing wrong?

推荐答案

在您的第一个示例中,原始" MIME数据的格式不正确:

In your first example, your "raw" MIME data is not formatted correctly:

  • 您缺少一堆必需的换行符.并且不要使用sLineBreak常量,因为其值是特定于平台的. MIME期望换行符专门使用CRLF. Indy具有该值的EOL常量.

  • You are missing a bunch of required line breaks. And don't use the sLineBreak constant, as its value is platform-specific. MIME expects line breaks to use CRLF specifically. Indy has an EOL constant for that value.

在封闭边界线的末端有一个错误的分号.

You have an erroneous semicolon on the end of the closing boundary line.

您也没有正确设置Request.AcceptEncoding属性.不要手动启用编码,除非您准备好在响应中手动处理它们(而您的代码则没有).如果将TIdZLibCompressorBase派生的组件(如TIdCompressorZLib)分配给TIdHTTP.Compressor属性,则TIdHTTP会为您处理gzipdeflate编码.不用担心br编码,它没有被广泛使用.简而言之,将Request.AcceptEncoding保留为默认设置,然后让TIdHTTP为您管理它.

You are also not setting the Request.AcceptEncoding property correctly. DO NOT enable encodings manually, unless you are prepared to actually handle them manually in responses (which your code is not). TIdHTTP handles gzip and deflate encodings for you, if you assign a TIdZLibCompressorBase-derived component, like TIdCompressorZLib, to the TIdHTTP.Compressor property. Don't worry about the br encoding, it is not widely used. In short, leave the Request.AcceptEncoding at its default and let TIdHTTP manage it for you.

您也没有正确设置Request.AcceptLanguage属性.您应该将其设置为'en-US,en;q=0.8',而不是'Accept-Language'.

You are also not setting the Request.AcceptLanguage property correctly. You should be setting it to 'en-US,en;q=0.8', not to 'Accept-Language'.

如果进行以下修复,您的第一个示例应该可以工作,例如:

Your first example should work if you make these fixes, eg:

function TIdFoo.SendIM(const AID, AMessage: string): Boolean;
const
  _URL = 'https://URL.com/SendMessage';
var
  Params   : TStringStream;
  Response : string;
  LMsg     : string;
begin
  Result := False;
  LMsg := '-----------------------------13932' + EOL +
          'Content-Type: application/json; charset=utf-8' + EOL +
          'Content-Description: message' + EOL +
          EOL +
          '{"message":{"Type":1,"body":"'+AMessage+'"},"to":["'+AID+'"]}' + EOL +
          '-----------------------------13932--' + EOL;
  Params := TStringStream.Create(LMsg, TEncoding.UTF8);
  try
    IdHTTP.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + FToken);
    IdHTTP.Request.CustomHeaders.AddValue('Origin', 'https://www.URL.com');
    IdHTTP.Request.UserAgent      := 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36';
    IdHTTP.Request.Accept         := '*/*';
    IdHTTP.Request.Referer        := 'https://www.URL.com/en-us/';
    IdHTTP.Request.Host           := 'URL.com';
    IdHTTP.Request.AcceptLanguage := 'en-US,en;q=0.8';
    IdHTTP.Request.ContentType    := 'multipart/mixed; boundary="---------------------------13932"';

    try
      Response := IdHTTP.Post(_URL, Params);
      Result := True;
    except
      on E: Exception do
        Writeln('Error on Send Message request: '#13#10, e.Message);
    end;
    Writeln(IdHTTP.Request.RawHeaders.Text);
  finally
    Params.Free;
  end;
end;

或者:

function TIdFoo.SendIM(const AID, AMessage: string): Boolean;
const
  _URL = 'https://URL.com/SendMessage';
var
  Params   : TMemoryStream;
  Response : string;
  LMsg     : string;
begin
  Result := False;
  Params := TMemoryStream.Create;
  try
    WriteStringToStream(Params, '-----------------------------13932' + EOL);
    WriteStringToStream(Params, 'Content-Type: application/json; charset=utf-8' + EOL);
    WriteStringToStream(Params, 'Content-Description: message' + EOL);
    WriteStringToStream(Params, EOL);
    WriteStringToStream(Params, '{"message":{"Type":1,"body":"'+AMessage+'"},"to":["'+AID+'"]}' + EOL, IndyTextEncoding_UTF8);
    WriteStringToStream(Params, '-----------------------------13932--' + EOL);
    Params.Position := 0;

    IdHTTP.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + FToken);
    IdHTTP.Request.CustomHeaders.AddValue('Origin', 'https://www.URL.com');
    IdHTTP.Request.UserAgent      := 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36';
    IdHTTP.Request.Accept         := '*/*';
    IdHTTP.Request.Referer        := 'https://www.URL.com/en-us/';
    IdHTTP.Request.Host           := 'URL.com';
    IdHTTP.Request.AcceptLanguage := 'en-US,en;q=0.8';
    IdHTTP.Request.ContentType    := 'multipart/mixed; boundary="---------------------------13932"';

    try
      Response := IdHTTP.Post(_URL, Params);
      Result := True;
    except
      on E: Exception do
        Writeln('Error on Send Message request: '#13#10, e.Message);
    end;
    Writeln(IdHTTP.Request.RawHeaders.Text);
  finally
    Params.Free;
  end;
end;

或者:

function TIdFoo.SendIM(const AID, AMessage: string): Boolean;
const
  _URL = 'https://URL.com/SendMessage';
var
  Params   : TMemoryStream;
  Response : string;
  LMsg     : string;
begin
  Result := False;
  Params := TMemoryStream.Create;
  try
    with TStreamWriter.Create(Params, TEncoding.UTF8) do
    try
      NewLine := EOL;
      WriteLine('-----------------------------13932');
      WriteLine('Content-Type: application/json; charset=utf-8');
      WriteLine('Content-Description: message');
      WriteLine;
      WriteLine('{"message":{"Type":1,"body":"'+AMessage+'"},"to":["'+AID+'"]}');
      WriteLine('-----------------------------13932--');
    finally
      Free;
    end;
    Params.Position := 0;

    IdHTTP.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + FToken);
    IdHTTP.Request.CustomHeaders.AddValue('Origin', 'https://www.URL.com');
    IdHTTP.Request.UserAgent      := 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36';
    IdHTTP.Request.Accept         := '*/*';
    IdHTTP.Request.Referer        := 'https://www.URL.com/en-us/';
    IdHTTP.Request.Host           := 'URL.com';
    IdHTTP.Request.AcceptLanguage := 'en-US,en;q=0.8';
    IdHTTP.Request.ContentType    := 'multipart/mixed; boundary="---------------------------13932"';

    try
      Response := IdHTTP.Post(_URL, Params);
      Result := True;
    except
      on E: Exception do
        Writeln('Error on Send Message request: '#13#10, e.Message);
    end;
    Writeln(IdHTTP.Request.RawHeaders.Text);
  finally
    Params.Free;
  end;
end;


在第二个示例中,您的原始"数据本身就是JSON,而不是包装它的任何MIME.您将MIME头放在不属于它们的HTTP头中.如果服务器需要MIME数据而不仅仅是原始JSON数据,则此示例将不起作用.


In your second example, your "raw" data is just the JSON by itself, not any MIME wrapping it. You are putting MIME headers in the HTTP headers, where they don't belong. This example will not work if the server expects MIME data and not just raw JSON data.

您还会在Request.AcceptEncodingRequest.AcceptLanguage属性上犯同样的错误.

You are also making the same mistakes with the Request.AcceptEncoding and Request.AcceptLanguage properties.

由于您以MIME格式发布数据,因此更容易处理此的方法是使用Indy的TIdMultipartFormDataStream类,并让它为您处理MIME格式.但是,该类当前不支持:

Since you are posting data in MIME format, an easier way to handle this would have been to use Indy's TIdMultipartFormDataStream class instead, and let it handle the MIME formatting for you. However, that class does not currently support:

  • 将流的RequestContentType属性设置为自定义值(在本例中为'multipart/mixed'而不是'multipart/form-data').但是,由于FRequestContentType成员是protected.您可以使用访问器类来完成此操作.

  • setting the stream's RequestContentType property to a custom value (in this case, 'multipart/mixed' instead of 'multipart/form-data'). Though, you can use an accessor class to accomplish this, since the FRequestContentType member is protected.

在各个字段上省略Content-Disposition: form-data标头.这可能会使不希望提交form-data的服务器跳闸.

omitting the Content-Disposition: form-data header on individual fields. This might trip up servers that are not expecting form-data submissions.

完全指定Content-Description MIME标头(请参见添加对用户定义的支持GitHub上Indy的问题跟踪器中的TIdMultipartFormDataDataStream 中的MIME标头.

specifying the Content-Description MIME header at all (see Add support for user-defined MIME headers in TIdMultipartFormDataStream in Indy's issue tracker on GitHub).

因此,您将不得不继续求助于手动格式化MIME数据.您只需要确保正确就可以.

So you will have to continue resorting to formatting the MIME data manually. You just have to make sure you get it right.

这篇关于IdHTTP如何发送原始正文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆