如何使用IdHTTPPostManDOS的形式发送消息:
http - IdHTTP如何发送原始正文-LMLPHP
http - IdHTTP如何发送原始正文-LMLPHP
我的第一次尝试如下:

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;

第二次尝试我是这样尝试的
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
我做错了什么,你能给我提个建议吗?

最佳答案

在第一个示例中,“原始”mime数据的格式不正确:
您缺少一堆必需的换行符。不要使用sLineBreak常量,因为它的值是平台特定的。mime希望换行符具体使用CRLF。indy有一个EOL常数。
在闭合边界线的末尾有一个错误的分号。
您也没有正确设置Request.AcceptEncoding属性。不要手动启用编码,除非您准备好在响应中手动处理它们(您的代码不是这样)。TIdHTTP为您处理gzipdeflate编码,如果您将TIdZLibCompressorBase派生组件(如TIdCompressorZLib)分配给TIdHTTP.Compressor属性。不用担心br编码,它没有被广泛使用。简而言之,将Request.AcceptEncoding保留为默认值,让TIdHTTP为您管理它。
您也没有正确设置Request.AcceptLanguage属性。您应该将其设置为'en-US,en;q=0.8',而不是'Accept-Language'
如果您进行了这些修复,您的第一个示例应该可以工作,例如:

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头中,它们不属于http头。如果服务器需要mime数据而不仅仅是原始json数据,则此示例将不起作用。
对于Request.AcceptEncodingRequest.AcceptLanguage属性,您也会犯同样的错误。
由于您是以mime格式发布数据,处理此问题的一个更简单的方法是使用indy的TIdMultipartFormDataStream类,并让它为您处理mime格式。但是,该类当前不支持:
将流的RequestContentType属性设置为自定义值(在本例中,'multipart/mixed'而不是'multipart/form-data')。不过,您可以使用访问器类来实现这一点,因为FRequestContentType成员是protected
省略单个字段上的Content-Disposition: form-data标题。这可能会导致不希望提交form-data的服务器出现故障。
完全指定Content-Descriptionmime头(请参阅github上indy's issue tracker中的Add support for user-defined MIME headers in TIdMultipartFormDataStream)。
因此,必须继续手动设置mime数据的格式。你只需要确保你做得对。

关于http - IdHTTP如何发送原始正文,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44665349/

10-13 02:43