За последние 24 часа нас посетили 22562 программиста и 1016 роботов. Сейчас ищут 692 программиста ...

Как отправить письмо с вложением (аттачем).

Тема в разделе "Работа с почтой", создана пользователем Sergey89, 30 янв 2008.

  1. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Сам по себе протокол не предназначен для отправки нетекстовой информации. Поэтому было введено расширение MIME. Оно позволяет помимо текстовой информации, отправлять вложения.

    Вот пример письма, в которое вложен текстовый документ:
    Код (Text):
    1. From: user@server.com
    2. To: admin@server.com
    3. Subject: =?utf-8?B?VGVzdCBtZXNzYWdlLg==?=
    4. MIME-Version: 1.0
    5. Content-Type: multipart/mixed; boundary="Boundarydadea6878885170f292e94279eeee0e6"
    6. --Boundarydadea6878885170f292e94279eeee0e6
    7. Content-Type: text/plain; charset="utf-8"
    8. Content-Transfer-Encoding: base64
    9.  
    10. SGVsbG8sIFdvcmxkIQ==
    11. --Boundarydadea6878885170f292e94279eeee0e6
    12. Content-Type: application/octet-stream
    13. Content-Transfer-Encoding: base64
    14. Content-Disposition: attachment; filename="document.txt"
    15.  
    16. 3fLuIO/w6Ozl8CDy5erx8 u7i7uPuIOTu6vPs5e3y4C4=
    17. --Boundarydadea6878885170f292e94279eeee0e6--
    Разберём его на куски.

    Код (Text):
    1. From: user@server.com
    2. To: admin@server.com
    3. Subject: =?utf-8?B?VGVzdCBtZXNzYWdlLg==?=
    Стандартные поля сообщения: От, Кому и Тема. Заметим, что тема в кодировке UTF-8 и закодирована при помощи base64, т.к. по стандарту в письме не должно быть символов с кодами > 128 (7bit encoding).

    Код (Text):
    1. MIME-Version: 1.0
    Определяет используемую версию MIME. Сейчас в ходу версия 1.0, возможностей которой, пока, хватает.

    Код (Text):
    1. Content-Type: multipart/mixed; boundary="Boundarydadea6878885170f292e94279eeee0e6"
    Эта строчка сообщает о том, что в письме содержится смешанный контент и определяет, так называемый, boundary. Boundary - своего рода ограничитель, применяемый для отделения разных частей письма. Подбирается самостоятельно на основе того, что он не должен встречаться в теле письма.

    Код (Text):
    1. --Boundarydadea6878885170f292e94279eeee0e6
    2. Content-Type: text/plain; charset="utf-8"
    3. Content-Transfer-Encoding: base64
    4.  
    5. SGVsbG8sIFdvcmxkIQ==
    Заголовки и текст письма, закодированный при помощи всё того же base64 в кодировке UTF-8. Данный блок должен начинаться с двух дефисов и boundary. После boundary обязательный перевод строки. Также не забываем разделить заголовки и текст новой строкой.

    Код (Text):
    1. --Boundarydadea6878885170f292e94279eeee0e6
    2. Content-Type: application/octet-stream
    3. Content-Transfer-Encoding: base64
    4. Content-Disposition: attachment; filename="document.txt"
    5.  
    6. 3fLuIO/w6Ozl8CDy5erx8u7i7uPuIOTu6vPs5e3y4C4=
    Само вложение так же состоит из двух частей: заголовков и тела. Начинаться должно так же с двух дефисов, boundary и перевода строки. Content-Type определяет тип содержимого. application/octet-stream - стандартный тип для бинарных данных, хотя в данном случае и приложен текстовый документ, его так же можно рассматривать, как поток байтов. Content-Transfer-Encoding определяет способ кодирования тела вложения. В данном случае это base64, который поддерживаю все популярные почтовые клиенты. Content-Disposition определяет то, как клиент должен отобразить файл. attachment указыват на что это вложенный файл с именем в filename. Тело письмо отделяется от заголовков пустой строкой.

    Код (Text):
    1. --Boundarydadea6878885170f292e94279eeee0e6--
    Последняя строка закрывает MIME документ. Она должна начинаться и заканчиваться с двух дефисов и boundary между ними.

    Во и всё. Позже расскажу как приложить несколько файлов, как приложить несколько картинок и отобразить их в HTML странице, как добавить альтернативное сообщение для браузеров без поддержки MIME ну и покажу пример реализации на PHP.
     
  2. Штаны

    Штаны Guest

    Sergey89, терпеливо ждем продолжения
     
  3. aperkot

    aperkot Активный пользователь

    С нами с:
    4 ноя 2009
    Сообщения:
    1
    Симпатии:
    0
    Отправляется файл но на почтових сайтах не показуется!

    Когда прикрепляю файл на почте уже этот файл выглядит как куча символов

    В чем может быть проьлема?

    Часть HTML письма отображается нормально.

    а часть прикрепленного файла отак:

    --093485703948503498504385034 Content-Type: application/octet-stream;name="phpqT13Bk" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="phpqT13Bk" /9j/4AAQSkZJRgABAgAAZABkAAD/7AARRHVja3kAAQAEAAAAOQAA/+4ADkFkb2JlAGTAAAAAAf/b AIQABwUFBQUFBwUFBwoGBgYKDAkHBwkMDQsLDAsLDREMDAwMDAwRDQ8QERAPDRQUFhYUFB4dHR0e ISEhISEhISEhIQEHCAgODA4aEREaHRcTFx0hISEhISEhISEhISEhISEhISEhISEhISEhISEhISEh ISEhISEhISEhISEhISEhISEh/8AAEQgA9QF8AwERAAIRAQMRAf/EAI8AAAAHAQEAAAAAAAAAAAAA AAABAgMEBQYHCAEBAQEBAAAAAAAAAAAAAAAAAAECAxAAAgEDAwIEBAQDBgMHAgcBAQIDABEEIRIF MQZBUSITYXEyFIFCFQeRoSOxwVJiMxZygiTR4fGSorJD8DTC4lNjg0QXVBEBAQEAAwEBAAAAAAAA AAAAABEBIQISMUH/2gAMAwEAAhEDEQA/AODxKdwIrKpZjDG6ggmoqWkbLHZtVI1+dFS8PHJBYAWU dT4UQ9/UVwH9F9b0U48bu39KS - десь еще куча текста

    093485703948503498504385034--

    Что может быть не так ????

    Проверял на двух почтах mail i google[/u]
     
  4. EvelRus

    EvelRus Активный пользователь

    С нами с:
    16 ноя 2006
    Сообщения:
    2.168
    Симпатии:
    0
    Адрес:
    Москва
    Вопрос, а как отправить html сообщение с картинками? Ведь картинки тоже вложения...
     
  5. moroz

    moroz Активный пользователь

    С нами с:
    13 дек 2010
    Сообщения:
    33
    Симпатии:
    0
    Спасибо.Но здесь конкретный файл вкладывается.А мне нужен вариант,когда ио ОБЗОРА выбирается любой файл ,прикрепляется и отправляется. Я свою тему выставила только что на форум,может поможете.
     
  6. vladislav_vld

    vladislav_vld Активный пользователь

    С нами с:
    4 дек 2011
    Сообщения:
    7
    Симпатии:
    0
    Адрес:
    Орел
    Сначала надо тогда файл загрузить на сервер, а потом прикрепить к письму. Загрузку можно сделать на ajax, без перезагрузки страницы. Поищите, скриптов загрузки достаточно много. Если это не так важно, то можно почитать Отправка письма с вложением.
     
  7. artem-Kuzmin

    artem-Kuzmin Активный пользователь

    С нами с:
    16 фев 2012
    Сообщения:
    809
    Симпатии:
    0
    Проще отправить с ссылками на картинки на своем сервере
     
  8. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    и письмом нельзя будет любоваться в оффлайне?
     
  9. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Довольно удобная штука (на мой взгляд) - class.phpmailer.php - там есть готовые методы для прикрепления картинок к письму. Чтобы вставить прикреплённое изображение в html-письмо - в атрибуте src тега img нужно написать

    cid:название_картинки

    Название картинки должно соответствовать названию, которое передали в метод AddEmbeddedImage вторым (или третьим) параметром. Я передаю и вторым и третьим одно и тоже:

    Код (PHP):
    1. <?php
    2. $html = '<html>
    3.     <head>
    4.         <meta http-equiv="Content-type" content="text/html; charset=Windows-1251" />
    5.         <title>Тема письма</title>
    6.     </head>
    7.     <body>
    8.         <div>
    9.             Картинка 1 ниже:<br />
    10.             <img src="cid:pict1.jpg" />
    11.         </div>
    12.         <br />
    13.         <br />
    14.         <div>
    15.             Картинка 2 ниже:<br />
    16.             <img src="cid:pict2.jpg" />
    17.         </div>
    18.     </body>
    19. </html>';
    20.  
    21. $path = dirname(__FILE__);
    22. require($path . DIRECTORY_SEPARATOR . 'class.phpmailer.php');
    23. $mailer = new PHPMailer();
    24. $mailer->From = 'admin@site.ru';
    25. $mailer->CharSet = 'Windows-1251';
    26. $mailer->FromName = 'site.ru admin';
    27. $mailer->Subject = 'Тема письма';
    28. $mailer->AddEmbeddedImage($path . DIRECTORY_SEPARATOR . 'img1.jpg', 'pict1.jpg', 'pict1.jpg', 'base64', 'image/jpeg');
    29. $mailer->AddEmbeddedImage($path . DIRECTORY_SEPARATOR . 'img2.jpg', 'pict2.jpg', 'pict2.jpg', 'base64', 'image/jpeg');
    30. $mailer->Body = $html;
    31. $mailer->IsHTML(true);
    32. $mailer->AddAddress('recipient@mail.ru');
    33. $sended = $mailer->Send();
    34. ?>
     
  10. qwert_ukg

    qwert_ukg Активный пользователь

    С нами с:
    20 июл 2010
    Сообщения:
    387
    Симпатии:
    0
    Адрес:
    Алмата
    интересно как же?
     
  11. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Всё просто - создаёшь на странице невидимый iframe, а у формы прописываешь target на этот iframe. Когда файл отправляется - ответ от сервера придёт в него. Далее с помощью JS смотришь, что там пришло и выполняешь нужные действия.
    Я обычно в таких случаях в этот iframe тоже отправляю некий JS-код, который дёрнет какую-то функцию родительского окна и заставит выполнять нужные действия.
     
  12. qwert_ukg

    qwert_ukg Активный пользователь

    С нами с:
    20 июл 2010
    Сообщения:
    387
    Симпатии:
    0
    Адрес:
    Алмата
    ну это не аяксом!
     
  13. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Почему же не аяксом? Тут JavaScript и PHP взаимодействуют для обмена данными клиента и сервера без перезагрузки - чем не аякс?
     
  14. qwert_ukg

    qwert_ukg Активный пользователь

    С нами с:
    20 июл 2010
    Сообщения:
    387
    Симпатии:
    0
    Адрес:
    Алмата
  15. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Ну, у меня такое понимание, что аякс - это сама технология, при которой пользователь что-то делает с сайтом - заполняет формы, отправляет данные и получает ответы от системы, оставаясь на той странице, которая у него загружена в браузере, то есть не перезагружается та видимая страница, на которой он находится, которая у него в браузере открыта. А каким именно методом это достигается - будь то xmlHttpRequest или обычная отправка формы в невидимый iframe и анализ пришедшего результата - вообще абсолютно пофигу. Суть от этого ничуть не меняется. Активная страница пользователя не перезагрузилась, а обмен данными идёт где-то там "за кулисами", и не важно как именно.
     
  16. qwert_ukg

    qwert_ukg Активный пользователь

    С нами с:
    20 июл 2010
    Сообщения:
    387
    Симпатии:
    0
    Адрес:
    Алмата
    в чем-то вы правы
     
  17. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    аякс это просто научили js просить браузер сходить по урлу и посмотреть что там.
     
  18. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    По-моему, ты говоришь про XMLHttpResponse / Microsoft.XMLHTTP. Но это не синонимы слова Ajax, на сколько я понимаю. Это лишь одна из его составляющих...
     
  19. qwert_ukg

    qwert_ukg Активный пользователь

    С нами с:
    20 июл 2010
    Сообщения:
    387
    Симпатии:
    0
    Адрес:
    Алмата
    в принципе аяксом можно назвать любой фоновый обмен данными клиента и сервера
     
  20. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.410
    Симпатии:
    1.768
    для этого есть слово "суть".
    все остальное - основные частоиспользуемые механизмы, которые сразу идут из коробки, но в принципе могут быть реализованы тремя строчками js.
     
  21. nvbpmgeorge

    nvbpmgeorge Новичок

    С нами с:
    11 фев 2014
    Сообщения:
    1
    Симпатии:
    0
    Не могу разобраться, помогите!

    Подскажите, пожалуйста, новичку.
    Исходные данные. Есть файл index.html:

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>Отправка сообщения с вложением</title>
    <link type="text/css" rel="stylesheet" href="style.css">
    </head>
    <body>
    <H3> <center><font color="#1E90FF">Отправка сообщения с вложением</font></H3>
    <center>
    <form action="simple_mail.php" enctype="multipart/form-data" method="post">
    <p>Кому: <input type="text" name="mail_to" maxlength="32"></p>
    <p>Subject: <input type="text" name="mail_subject" maxlength="64"></p>
    <p>Сообщение: <textarea cols="50" rows="8" name="mail_msg"></textarea></p>
    <p>File: <input type="file" name="mail_file" maxlength="64"></p>
    <p><input type="submit" value="Отправить"></p>
    </form>
    </table>
    </center>
    </body>
    </html>

    Есть файл simple_mail.php:
    <?php
    if(empty($_POST['mail_to'])) exit("Введите адрес получателя");
    // проверяем правильности заполнения с помощью регулярного выражения
    if (!preg_match("|^([a-z0-9_\.\-]{1,20})@([a-z0-9\.\-]{1,20})\.([a-z]{2,4})|is",
    strtolower($email))) exit("Введите адрес в виде somebody@server.com");
    $picture = "";
    // Если поле выбора вложения не пустое - закачиваем его на сервер
    if (!empty($_FILES['mail_file']['tmp_name']))
    {
    // Закачиваем файл
    $path = $_FILES['mail_file']['name'];
    if (copy($_FILES['mail_file']['tmp_name'], $path)) $picture = $path;
    }
    $thm = $_POST['mail_subject'];
    $msg = $_POST['mail_msg'];
    $mail_to = $_POST['mail_to'];
    // Отправляем почтовое сообщение
    if(empty($picture)) mail($mail_to, $thm, $msg);
    else send_mail($mail_to, $thm, $msg, $picture);
    // Вспомогательная функция для отправки почтового сообщения с вложением (Trianon)
    function send_mail($mail_to, $thema, $html, $path)
    { if ($path) {
    $fp = fopen($path,"rb");
    if (!$fp)
    { print "Cannot open file";
    exit();
    }
    $file = fread($fp, filesize($path));
    fclose($fp);
    }
    $name = "file.ext"; // в этой переменной надо сформировать имя файла (без всякого пути)
    $EOL = "\r\n"; // ограничитель строк, некоторые почтовые сервера требуют \n - подобрать опытным путём
    $boundary = "--".md5(uniqid(time())); // любая строка, которой не будет ниже в потоке данных.
    $headers = "MIME-Version: 1.0;$EOL";
    $headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"$EOL";
    $headers .= "From: address@server.com";

    $multipart = "--$boundary$EOL";
    $multipart .= "Content-Type: text/html; charset=windows-1251$EOL";
    $multipart .= "Content-Transfer-Encoding: base64$EOL";
    $multipart .= $EOL; // раздел между заголовками и телом html-части
    $multipart .= chunk_split(base64_encode($html));

    $multipart .= "$EOL--$boundary$EOL";
    $multipart .= "Content-Type: application/octet-stream; name=\"$name\"$EOL";
    $multipart .= "Content-Transfer-Encoding: base64$EOL";
    $multipart .= "Content-Disposition: attachment; filename=\"$name\"$EOL";
    $multipart .= $EOL; // раздел между заголовками и телом прикрепленного файла
    $multipart .= chunk_split(base64_encode($file));

    $multipart .= "$EOL--$boundary--$EOL";

    if(!mail($mail_to, $thema, $multipart, $headers))
    {return False; //если не письмо не отправлено
    }
    else { //// если письмо отправлено
    return True;
    }
    exit;
    }
    ?>

    Проблема в следующем: все поля формы, включая вложения, заполнены.
    После нажатия "Отправить", в браузере появляется следующее сообщение:


    <?php
    if(empty($_POST['mail_to'])) exit("Введите адрес получателя");
    // проверяем правильности заполнения с помощью регулярного выражения
    if (!preg_match("|^([a-z0-9_\.\-]{1,20})@([a-z0-9\.\-]{1,20})\.([a-z]{2,4})|is",
    strtolower($email))) exit("Введите адрес в виде somebody@server.com");
    $picture = "";
    // Если поле выбора вложения не пустое - закачиваем его на сервер
    if (!empty($_FILES['mail_file']['tmp_name']))
    {
    // Закачиваем файл
    $path = $_FILES['mail_file']['name'];
    if (copy($_FILES['mail_file']['tmp_name'], $path)) $picture = $path;
    }
    $thm = $_POST['mail_subject'];
    $msg = $_POST['mail_msg'];
    $mail_to = $_POST['mail_to'];
    // Отправляем почтовое сообщение
    if(empty($picture)) mail($mail_to, $thm, $msg);
    else send_mail($mail_to, $thm, $msg, $picture);
    // Вспомогательная функция для отправки почтового сообщения с вложением (Trianon)
    function send_mail($mail_to, $thema, $html, $path)
    { if ($path) {
    $fp = fopen($path,"rb");
    if (!$fp)
    { print "Cannot open file";
    exit();
    }
    $file = fread($fp, filesize($path));
    fclose($fp);
    }
    $name = "file.ext"; // в этой переменной надо сформировать имя файла (без всякого пути)
    $EOL = "\r\n"; // ограничитель строк, некоторые почтовые сервера требуют \n - подобрать опытным путём
    $boundary = "--".md5(uniqid(time())); // любая строка, которой не будет ниже в потоке данных.
    $headers = "MIME-Version: 1.0;$EOL";
    $headers .= "Content-Type: multipart/mixed; boundary=\"$boundary\"$EOL";
    $headers .= "From: address@server.com";

    $multipart = "--$boundary$EOL";
    $multipart .= "Content-Type: text/html; charset=windows-1251$EOL";
    $multipart .= "Content-Transfer-Encoding: base64$EOL";
    $multipart .= $EOL; // раздел между заголовками и телом html-части
    $multipart .= chunk_split(base64_encode($html));

    $multipart .= "$EOL--$boundary$EOL";
    $multipart .= "Content-Type: application/octet-stream; name=\"$name\"$EOL";
    $multipart .= "Content-Transfer-Encoding: base64$EOL";
    $multipart .= "Content-Disposition: attachment; filename=\"$name\"$EOL";
    $multipart .= $EOL; // раздел между заголовками и телом прикрепленного файла
    $multipart .= chunk_split(base64_encode($file));

    $multipart .= "$EOL--$boundary--$EOL";

    if(!mail($mail_to, $thema, $multipart, $headers))
    {return False; //если не письмо не отправлено
    }
    else { //// если письмо отправлено
    return True;
    }
    exit;
    }
    ?>

    Вопрос: что я делаю не так?
     
  22. sobachnik

    sobachnik Старожил

    С нами с:
    20 апр 2007
    Сообщения:
    3.380
    Симпатии:
    13
    Адрес:
    Дмитров, МО
    Видимо на сервере нету PHP. Используйте другой хостинг.
     
  23. Lihatskiy

    Lihatskiy Новичок

    С нами с:
    15 дек 2014
    Сообщения:
    1
    Симпатии:
    0
    Могу предложить PHP библиотеку для отправки почтовых сообщений.

    Возможности библиотеки:
    • Работа с Mail, Sendmail и SMTP
      Массовая рассылка
      CC и BCCs
      HTML или Обычный текст писем
      Вложения
      Перенос строк
      Приоритеты
      BCC Batch Mode, позволяет разбивать большие списки адресов на мелкие пакеты.
      Инструменты отладки

    Скачиваем по ссылке, подключаем файл.

    Пример отправки письма с вложением:
    Код (Text):
    1. $email = new Email();
    2.  
    3. $email->from("your@your-site.com", "Your Name");
    4. $email->to("someone@example.com");
    5. $email->subject("Тема письма");
    6. $email->message("Тут моё сообщение");
    7. $email->attach("/path/to/file.ext");
    8.  
    9. $email->send();
    10.  
    11. echo $email->print_debugger();
    P.S. Взято из фреймворка CodeIgniter. Можно подключать и использовать на любом сайте написанном на PHP, независимо от движка/фреймворка/CMS.