Я вижу несколько проблем с вашим кодом.
Вы ошибочно экранировали \
символов в путях к файлам Это необходимо в таких языках, как C и C ++, но совсем не нужно в Delphi, поэтому избавьтесь от него.
Изменить это:
Afilename := 'C:\\Users\\Admin\\Documents\\arrival and departure small.pdf';
К этому:
Afilename := 'C:\Users\Admin\Documents\arrival and departure small.pdf';
Следующая проблема, которую я вижу, заключается в том, что вы неправильно называете поля вложенных файлов при добавлении их в TIdMultipartFormDataStream
.
При вызове AddFile()
вы передаете полный путь к файлу как есть параметру AFieldName
вместо использования имен, таких как file0
, file1
и т. Д., Как показано в примерах Elastic.
Изменить это:
FormData.Addfile(filenames[i], filenames[i],MIMEStr);
К этому 1 :
FormData.AddFile('file'+IntToStr(i), filenames[i], MIMEStr);
1: к вашему сведению, нет необходимости вызывать GetMIMETypeForFile()
вручную, AddFile()
вызывает GetMIMETypeForFile()
внутри вас, если вы не предоставите строку для параметра AContentType
, например, FormData.AddFile('file'+IntToStr(i), filenames[i]);
Вы допустили аналогичную ошибку, когда пытались использовать AddFormField()
вместо AddFile()
для добавления вложений. Вы использовали фактическое содержимое данных каждого файла для параметра AFieldName
вместо использования содержимого для параметра AFieldValue
.
В этом случае измените это:
FormData.AddFormField(AttachmentContent.ToString,filenames[i]);
К этому:
FormData.AddFormField('file'+IntToStr(i), AttachmentContent.ToString, '', MIMEStr, filenames[i]);
Или, так как вы открываете TFileStream
объекты самостоятельно, вы можете использовать перегруженный метод AddFormField()
, который принимает TStream
в качестве ввода (просто убедитесь, что НЕ освобождайте TStream
объекты до тех пор, пока вы не закончите использовать TIdMultipartFormDataStream
!):
AttachmentContent := TFileStream.Create(filenames[i], fmOpenRead);
FormData.AddFormField('file'+IntToStr(i), MIMEStr, '', AttachmentContent, filenames[i]);
Сказав это, попробуйте что-то вроде этого:
function TForm1.Upload(url: string; params, filenames: TStrings): string;
var
FormData : TIdMultiPartFormDataStream;
ResponseText : string;
i : integer;
begin
FormData := TIdMultiPartFormDataStream.Create;
try
for i := 0 to params.Count - 1 do
FormData.AddFormField(params.Names[i], params.ValueFromIndex[i]);
for i := 0 to filenames.Count - 1 do
FormData.AddFile('file'+IntToStr(i), filenames[i]);
ResponseText := IdHTTP1.Post(url, FormData);
Memo1.Text := ResponseText; //debug
finally
FormData.Free;
end;
end;
procedure TForm1.btnSendbyElastic(Sender: TObject);
var
Params, Filenames : TStringList;
url, Afilename : string;
begin
Afilename := 'C:\Users\Admin\Documents\arrival and departure small.pdf';
Params := TStringList.Create;
try
Params.Add('apikey=' + ELASTIC_MAIL_API_KEY);
Params.Add('from=' + ELASTIC_EMAIL_FROM_EMAIL);
Params.Add('fromname=' + ELASTIC_EMAIL_FROM_NAME);
Params.Add('Subject=' + 'The Subject');
Params.Add('bodyHtml=' + '<h1>Html Body</h1>');
Params.Add('bodyText=' + 'Text Body');
Params.Add('to=' + THE_RECIPIENT_ADDRESS);
Filenames := TStringList.Create;
try
Filenames.Add(Afilename);
url := ELASTIC_EMAIL_EMAIL_SEND;
Upload(url, params, filenames);
finally
Filenames.Free;
end;
finally
Params.Free;
end;
end;
Наконец, в документации Elastic ничего не говорится о кодировке, необходимой для имен файлов, которые содержат не-ASCII / зарезервированные символы. И существуют противоречивые стандарты относительно того, как такие имена файлов должны кодироваться при передаче по HTTP. По умолчанию TIdMultipartFormDataStream
кодирует имена файлов в соответствии с RFC 2047 . Если это оказывается проблемой для Elastic (ваш пример имени файла содержит пробелы в нем, я забываю, кодирует ли TIdMultipartFormDataStream
RFC-имя файла из-за пробелов или нет, надеюсь, нет), вы можете отключить TIdMultipartFormDataStream
' s кодировку по умолчанию, установив для свойства уязвимого файла TIdFormDataField.HeaderEncoding
значение '8'
(для 8-битной), а затем для свойства TIdFormDataField.FileName
можно установить любую кодировку, какую вы хотите:
with FormData.AddFile('file'+IntToStr(i), filenames[i]) do
begin
HeaderEncoding := '8';
FileName := EncodeFilenameMyWay(ExtractFileName(filenames[i]));
end;