Подписка

добавить на Яндекс

Наши проекты

Delphi+Google

Google API

Google API в Delphi - проект с открытым исходным кодом.

Chrono

Chrono

Хронометр - программа для ведения списка задач.

ODFProc

ODFProc

ODFProc - работа с документами OpenOffice в Lazarus и FreePascal.

Поддержка блога

А тут я коплю на лицензию Delphi XE на iPad =).
Сумма пожертвования не фиксирована.

Публикации

Год назад

Случайный пост

Последние

Сообщения форума

Комментарии

Социальные сети

Google

Facebook

Twitter

Опрос

Вы сейчас или в ближайшем обозримом будущем планируете разрабатывать кроссплатформенное приложение с использованием Firemonkey?



Loading ... Loading ...

Блоги и сообщества

Статьи по Delphi DelphiFeeds.ru - Все Delphi-блоги Рунета Сообщество умных людей VR-Online.RU Бесплатный журнал для программистов и всех, кто интересуется IT Статьи и уроки по Delphi Новостной блог о высоких технологиях
Система Orphus
Опубликовал Vlad 8 марта 2010 в 20:25.
Категории: Delphi в Web.


В прошлой статье про использование Synapse для отправки писем мы разработали простенькое приложение для отправки текстового сообщения на e-mail.  Сегодня доработаем процедуру отправки письма, а именно, сделаем возможность отпраки на e-mail любых файлов (вложений).

Вкратце напомню содержание предыдущей статьи по Synapse и SMTP. Для работы с электронной почтой мы использовали следующие модули библиотеки: smtpsend, mimemess и mimepart.


Отправка писем происходила по следующей схеме:

  1. Создавался объект TMimeMess для которого в заголовках указывались тема письма, адрес отправителя и адреса получателей
  2. Далее для объекта TMimeMess создавался корневой элемент сообщения, имеющий тип TMimePart
  3. В TMimePart добавлялся либо текст, либо HTML-код
  4. Последовательно вызывались два метода: метод объекта TMimeMess для кодирования письма - EncodeMessage и метод SendToRaw для отправки сообщения.

Сегодня немного расширим функциональность нашего приложения и отправим на почту вместе с текстом любой файл.

Для добавления в тело сообщения файлов в Synapse предусмотрены следующие методы объекта TMimeMess:

function AddPartBinary(const Stream: TStream; const FileName: string; const PartParent: TMimePart): TMimepart;

добавляет в содержимое сообщения бинарные данные из потока. При этом MIME-тип для вложения определяется автоматически по  расширению файла (FileName), а все данные беруться из потока Stream.

function AddPartBinaryFromFile(const FileName: string; const PartParent: TMimePart): TMimepart;

Также добавляет вложение как и AddPartBinary, но, в отличие от предыдущего метода не требует указания потока с данными. MIME-тип определяется автоматически.

Воспользуемся вторым методом, т.е. AddPartBinaryFromFile и отправим на почту, например, изображение. Процедуру для отправки письма возьмем из предыдущей статьи, но немного её дополним:

Procedure SendMail (pHost, pSubject, pTo, pFrom , pTextBody, pHTMLBody : string);
    var tmpMsg : TMimeMess;
        tmpStringList : TStringList;
        tmpMIMEPart : TMimePart;
begin
    tmpMsg := TMimeMess.Create;
    tmpStringList := TStringList.Create;
    try
        // Headers
        tmpMsg.Header.Subject := pSubject;
        tmpMsg.Header.From := pFrom;
        tmpMsg.Header.ToList.Add(pTo);
 
        // MIMe Parts
        tmpMIMEPart := tmpMsg.AddPartMultipart('alternate',nil);
 
        if length(pTextBody)>0 then
           begin
             tmpStringList.Text := pTextBody;
             tmpMsg.AddPartText(tmpStringList, tmpMIMEPart);
           end
        else
          begin
            tmpStringList.Text := pHTMLBody;
            tmpMsg.AddPartHTML(tmpStringList, tmpMIMEPart);
          end;
 
        if Form1.Edit1.Text<>'' then
            tmpMsg.AddPartBinaryFromFile(Form1.Edit1.Text,tmpMIMEPart)
        // кодируем и отправляем
        tmpMsg.EncodeMessage;
        smtpsend.SendToRaw(pFrom, pTo, pHost, tmpMsg.Lines, 'login', 'password');
 
    finally
        tmpMsg.Free;
        tmpStringList.Free;
    end;
end;

Мы добавили в процедуру всего две строки кода:

if Form1.Edit1.Text<>'' then
tmpMsg.AddPartBinaryFromFile(Form1.Edit1.Text,tmpMIMEPart)

Для того, чтобы отправить на почту файл. При этом указали корневой элемент tmpMIMEPart: TMimePart.
Аналогичным образом в письмо можно добавить любое количество, любых файлов. Остается только добавить, что в Synapse автоматически распознаются следующие MIME-типы и подтипы (по расширению файла):

Расширение Тип Подтип
AU audio basic
MP2 mpeg
MP3 mpeg
RA x-realaudio
SND basic
WAV x-wav
MID midi
AVI video x-msvideo
MOV quicktime
MPEG MPEG
MPG MPEG
QT quicktime
DOC application MSWord
EPS Postscript
PS Postscript
RTF RTF
PDF PDF
WPD Wordperfect5.1
ZIP ZIP
BMP image BMP
GIF GIF
JPEG JPEG
JPG JPEG
PNG PNG
TIF TIFF
TIFF TIFF

Для всех остальных файлов выставляется тип application с подтипом octet-stream. Если есть желание добавить в библиотеку распознавание других типов файлов, то дополните массив констант MimeType в модуле mimepart.

-----------------------
Быстрое создание и продвижение сайтов в Санкт-Петербурге. Хорошие акции и подарки!
Вроде бы март на дворе, а на улице мороз. В квартире тоже холодно, хоть отопительный котел покупай и обогревайся самомтоятельно.
-----------------------
Понравилась статья? Тогда:
Делись! Загружай! Плюсуй!
   Отправить PDF на   
Читай ещё статьи на WebDelphi.ru

Комментарии (8)

WP_Cloudy
  • Сергей пишет:

    Здравствуйте, подскажите, пожалуйста как отправить файл по http методом multipart/form-data? Пытался переделать этот пример, но безуспешно, нигде по этому вопросу информации не нашел.

  • Vlad пишет:

    Так, а в чём там проблема? Вставляете заголовок в запрос, каждую часть разделяете грницей + пустая строка и отправляете.

  • Сергей пишет:

    делаю так:


    StringList := TStringList.Create;
    tmpMsg := TMimeMess.Create;
    Http:=THTTPSend.Create;
    tmpMIMEPart := tmpMsg.AddPartMultipart('alternate',nil);
    data1:=TStringStream.Create('');
    http.Clear;
    http.MimeType:='multipart/form-data; boundary=—————————41184676334';
    stringlist.Add('method=pos');
    stringlist.Add('key=71a046f65057ff99dab062509ab4bad9');
    tmpmsg.AddPartMess(stringlist,tmpMIMEPart) ;
    tmpmsg.AddPartBinaryFromFile('1.jpg',tmpMIMEPart);
    tmpmsg.Lines.SaveToStream(data1);

    http.Document.LoadFromStream(data1);

    Но отправляется просто пустой post запрос

  • Vlad пишет:

    А зачем вы используете TMimeMess вместе с HTTPSend? Есть же нормальный класс TSMTPSend для отправки писем с вложениями. Это первое. Второе, boudary вы определили, а где используется его значение (boundary=—————————41184676334)? Не проще ли тогда уже использовать код, который я приводил здесь?

  • Сергей пишет:

    Спасибо, разобрался, нашел нужную функцию в демо синапса и немного переделал


    function ProxyHttpPostFile(const URL, FieldName, FileName: string;
    const Data: TStream; const ResultData: TStrings): Boolean;
    const
    CRLF = #$0D + #$0A;
    var
    HTTP: THTTPSend;
    Bound, s: string;
    begin
    Bound := IntToHex(Random(MaxInt), 8) + '_Synapse_boundary';
    HTTP := THTTPSend.Create;
    try

    s := '--' + Bound + CRLF;
    s := s + 'content-disposition: form-data; name="method"'+ crlf+ crlf;
    s:= s +'post'+crlf;
    HTTP.Document.Write(Pointer(s)^, Length(s));

    s := '--' + Bound + CRLF;
    s := s + 'content-disposition: form-data; name="key"'+ crlf+crlf;
    s:= s +'79bfdb771700dbd4bc280fedc0e11111'+crlf;
    HTTP.Document.Write(Pointer(s)^, Length(s));

    s := '--' + Bound + CRLF;
    s := s + 'content-disposition: form-data; name="' + FieldName + '";';
    s := s + ' filename="' + FileName +'"' + CRLF;
    s := s + 'Content-Type: Application/octet-string' + CRLF + CRLF;
    HTTP.Document.Write(Pointer(s)^, Length(s));
    HTTP.Document.CopyFrom(Data, 0);
    s := CRLF + '--' + Bound + '--' + CRLF;
    HTTP.Document.Write(Pointer(s)^, Length(s));
    HTTP.MimeType := 'multipart/form-data, boundary=' + Bound;
    Result := HTTP.HTTPMethod('POST', URL);
    ResultData.LoadFromStream(HTTP.Document);
    finally
    HTTP.Free;
    end;
    end;

    Может кому пригодится — отправка капчи на сервис antigate

  • Сергей пишет:

    p.s тэг [code] почему-то охватывает не все вложение

  • jskorvin пишет:

    Сергей, спасибо! Уже второй раз пригождается, примеров по синапсу в сети крайне мало =(

  • andyshark пишет:

    Столкнулся с интересным приколом Синапса — в некоторых случаях почта НЕ отправляется. Обычно все проходило нормально всегда, пользовал SendToRaw и проблем не было. Единственное почему-то ну душа к TMimeMess не прикипела, в итоге пользую для формирования письма TSakMsg (не пинать — так хочется). Смысл один по любому — объьект формирует текст письма и потом его отправляю.

    И вот недавно попалось машин 5-7 которые не могут отправить письмо! Версии полностью идентичные, от операционки данная проблема точно не зависит, т.к. вылазит однозначно на ХР, про другие не помню. Но много других машин с ХР письма отправляют! Общей закономерности пока даже не заметил :-(

    Попробовал переписать отправку через обьект TSMTPSend — та же фигня. Правда один клиент сказал что письмо сначала отправилось, но вот второй и третий раз такой фокус не прошел.

    Самое большое заподло — на моих компах все работает блин. А ехать к клиентам  и ставить там ДЕльфю… Ноненс :-(

    Может у кого есть мысли что смотреть хотя бы!

Ваш ответ

Внимание: Все комментарии модерируются, и это может вызвать задержку их публикации. Отправлять комментарий заново не требуется.

Пожалуйста, заключайте исходный код в тэги [code][/code].
Если код большой, то воспользуйтесь Вставкой кода на отдельной странице и оставьте в комментарии ссылку на исходник

   


naruto