Особенности обработки HTML-писем

    Здравствуйте, хабраюзеры!

    Недавно довелось копаться с рассылкой писем в HTML-формате. Есть много статей, написанных на тему валидной вёрстки рассылок, однако здесь речь пойдёт не об этом. Известно, что у каждого почтовика есть свои особенности отображения HTML-письма. Меня заинтересовали эти особенности и различия в отображении письма на разных почтовиках.

    Под исследование попали три моих почтовых ящика в службах mail.ru, yandex.ru и gmail.com. Был написан скрипт, который отправлял на них одно и то же письмо в html формате. С помощью него я прогнал несколько вариантов и сравнил результаты. Вот что получилось:

    Тег body


    Тело письма, отображаемого почтовиками, начинается с тега body. Оно и понятно — всё письмо содержится именно в нём. Однако сам тег body может содержать атрибут style. В каждом почтовике тело письма представляется div'ом, однако не все переносят в этот div содержимое style.
    • Mail.ru — Тег body заменяется на <div id='style_id_BODY'>, где id — идентификатор пользователя, передаваемый в строке GET запроса. Атрибут style теряется. Кроме того, теряются любые другие атрибуты, задаваемые для тега body.
    • Yandex.ru — Тег body меняется на <div class='b-message-body__content'>. Стили не переносятся, как и любые другие атрибуты тега body.
    • Gmail.com — Тег body меняется на обычный div, стили переносятся. Кроме того, в этот div попадают атрибуты, установленные для body (имеются ввиду атрибуты типа background).


    Особенности переноса атрибута style


    Атрибут style зачастую анализируется почтовой машиной и может быть изменён перед отправкой пользователю. Как это происходит на исследуемых почтовиках:
    • Mail.ru — Обработка атрибута style производится по принципу «всё разрешено, что явно не запрещено». Пока удалось обнаружить, что под запрет попадает position: absolute.
    • Yandex.ru — Атрибуты style проходят предварительную обработку. Незнакомые стили (ну и соответственно, ошибки) не пропускаются. Обрезание стилей происходит таким образом, что в письмо, отображаемое клиенту попадают все стили до первого неизвестного. Таким образом, конструкция width:100px;some-new-style:new;background-color:#CCC; будет заменена на width:100px;
    • Gmail.com — Атрибуты style также проходят предварительную обработку, однако в этом случае требования более жёсткие, чем у Yandex.ru. Если в значении атрибута будет найден хотя бы один недопустимый стиль, весь атрибут игнорируется.


    Отрицательные значения


    Во всех статьях по вёрстке HTML-рассылок неоднократно упоминается, что про отрицательные значения (например в margin) можно забыть. Результат тестов вполне ожидаемый:
    • Mail.rumargin-left:-100px; — работает.
    • Yandex.rumargin-left:-100px; — не работает.
    • Gmail.commargin-left:-100px; -не работает.

    Атрибут margin в Mail.ru пропускается только благодаря тому, что стили там не проходят предварительной обработки.

    Поддержка CSS3


    CSS 3 на данный момент находится в разработке, и некоторые почтовики считают определённые атрибуты недопустимыми. Итак, протестируем на наших трёх клиентах некоторые правила CSS3:

    Mail.ru


    Полная поддержка CSS3 и любых других браузерно-зависимых атрибутов ввиду очень лояльной фильтрации тега style.

    Yandex.ru


    • linear-gradient — да
    • box-shadow — нет
    • border-radius — да
    • text-shadow — нет
    • word-wrap — нет
    • resize — нет
    • несколько background'ов — да
    • border-image -да

    Gmail.com


    • linear-gradient — нет
    • box-shadow — нет
    • border-radius — да
    • text-shadow — да
    • word-wrap — да
    • resize — нет
    • несколько background'ов — да
    • border-image -нет


    CSS height


    Атрибут height поддерживается не всеми почтовиками.
    • Mail.ru — поддерживается.
    • Yandex.ru — поддерживается.
    • Gmail.com — не поддерживается, заменяется на min-height.


    UPD: В комментариях выяснилось, что уловки типа javascript:*** и expression:*** блокируются системой безопасности mail.ru.
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 19
    • +1
      Нет почты на mail.ru, по этому не могу проверить. Что будет если

      <b style="display:block;position:absolute;left:0;top:0;width:100%;height:100%;background-color:red;font-size:36px;">Отправьте SMS на короткий номер...</b>
      

      Ведь все стили проходят, если я правильно понял?
      • 0
        Пока удалось обнаружить, что под запрет попадает position: absolute.
        • +2
          Это было добавлено уже после, см. обсуждение ниже ↓
      • +2
        Вот результат:
        <b style="display:block;;width:100%;height:100%;background-color:red;font-size:36px;" id="mailru-webagent-gen-43">Отправьте SMS на короткий номер...</b>
        Да, positon: absolute, и всё что с ним связано не пропускает.
        • 0
          В таком случае поправьте топик — фильтрация стилей в mail.ru все-таки есть.
        • 0
          Mail.ru обрабатывает теги по принципу «всё разрешено, что явно не запрещено».
          Yandex.ru и Gamil.com — по принцпу «всё запрещено, что явно не разрешено».

          Пробовал подставлять несуществующие правила css, mail.ru их пропускает.
        • 0
          Gmail.com — Тег body меняется на обычный div, стили переносятся. Кроме того, в этот div попадают атрибуты, установленные для body (имеются ввиду атрибуты типа background).
          По-моему, background как раз не проходит. Видимо, это связано с тем, что на GMail могут быть темы, и письмо будет показано на полупрозрачном белом фоне, который не так просто сделать белым, если у вас например джипеги с белым фоном (а png-файлы будут неприлично большими). Поэкспериментируйте сами, установив тему оформления на ящике GMail.
          • 0
            <div background="http://***/templates/default/images/background.png" style="min-height:100px;background-color:#e1e1e4;background:url('http://***/templates/default/images/background.png') 50% 50% fixed no-repeat;color:#fff;font-family:Calibri;font-size:14px;line-height:1.22">

            Это со страницы письма. Тема у меня стоит.
            • 0
              И работает правильно?

              P.S. Не знаю, какая у вас картинка, но белый текст на светло-сером фоне как-то не очень.
          • 0
            У кого есть IE6 и почта на mail.ru пробуем еще так:

            <b style="background-image:url(javascript:alert('HabraHabr'))">Ха-ха-ха!</b>
            

            Или так: (должно работать и в IE7)

            <b style="width:expression(alert('HabraHabr'));">Ха-ха!!!</b>
            
            • 0
              В IETester, режим IE6, под письмом:

              ВНИМАНИЕ!
              Данное письмо содержит потенциально опасный HTML-код, заблокированный системой безопасности.
              Возможно, оно отображается неправильно.
              • 0
                javascript:*** не пропускает система безопасности.
                • +4
                  OK, пробуем так:

                  <b style="background-image:url(&#1;JaVaScRiPt:AlErT('Habr'))">qwerty</b>
                  

                  Или так:

                  <b style="background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029">test</b>
                  

                  Прошу прощения, что засоряю комментарии к топику.
                  • 0
                    Выложите скрипт, давайте пошерстим интересные варианты, ибо особенность mail.ru не может не радовать с точки зрения возможных косяков.
                    • 0
                      Скрипт простейший. Я использую PHPMailer, просто отправляю через него письмо. Что-то вроде этого:

                      $users = array(...); foreach($emails as $email) { try{ $mail = new PHPMailer(true); $mail->AddAddress($email); $mail->SetFrom('me@me.org', 'I am'); $mail->Subject = $title; $mail->MsgHTML(file_get_contents('mail.html')); $mail->CharSet = 'utf-8'; $mail->IsHTML(true); $mail->Send(); }catch(Exception $e){} }
                      • 0
                        Извиняюсь)

                        $users = array(...);

                        foreach($emails as $email)
                        {
                        try{
                        $mail = new PHPMailer(true);
                        $mail->AddAddress($email);
                        $mail->SetFrom('me@me.org', 'I am');
                        $mail->Subject = $title;
                        $mail->MsgHTML(file_get_contents('mail.html'));
                        $mail->CharSet = 'utf-8';
                        $mail->IsHTML(true);
                        $mail->Send();
                        }catch(Exception $e){}
                        }
                    • +4
                      Ах да, чуть не забыл! vbscript же есть :-)

                      Не уверен, что будет работать, но попробовать стоит:

                      <b style="background-image:url(vbscript:msgbox('HabraHabr'))">Ха-ха-ха!</b>
                      
                • +1
                  В Mail.ru вырезаются тег <style>, атрибут class и атрибуты событий (onclick, onload и т.д.). Из атрибута style вырезаются все правила, связанные с позиционированием. К тому же у блока, в котором отображается тело письма, применено свойство overflow, поэтому «выйти» за пределы контейнера и перекрыть элементы интерфейся вряд ли получится.
                  image

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.