Удалять изображения из html так же, как gmail для электронных писем без включенного изображения

Я пишу простой редактор HTML-редакторов электронной почты на PHP, а также показываю демонстрацию того, как это будет выглядеть.

Я думаю, было бы очень полезно показать пользователю, как это будет выглядеть в почтовом клиенте, таком как gmail с отключенными изображениями.

Каков мой лучший подход для этого? Кто-нибудь знает, как это делается в gmail / hotmail и т. Д.?

Я просто удаляю img -> src и css background: url с выражением reg?

Я хотел бы удалить фоновые части из: background="url" используемого в таблицах и background-image:url(url); Использованный встроенный css

Я нашел этот вопрос, который имеет такую ​​же идею, хотя я бы хотел удалить удаленные img и backrgound-изображения из текста HTML.

Или этот код может быть изменен для работы с фоновыми изображениями?

Я бы также предложил использовать PHP DOM вместо регулярного выражения, которые часто бывают неточными. Вот пример кода, который вы можете использовать, чтобы удалить все теги img и все фоновые атрибуты из вашей строки:

 // ...loading the DOM $dom = new DOMDocument(); @$dom->loadHTML($string); // Using @ to hide any parse warning sometimes resulting from markup errors $dom->preserveWhiteSpace = false; // Here we strip all the img tags in the document $images = $dom->getElementsByTagName('img'); $imgs = array(); foreach($images as $img) { $imgs[] = $img; } foreach($imgs as $img) { $img->parentNode->removeChild($img); } // This part strips all 'background' attribute in (all) the body tag(s) $bodies = $dom->getElementsByTagName('body'); $bodybg = array(); foreach($bodies as $bg) { $bodybg[] = $bg; } foreach($bodybg as $bg) { $bg->removeAttribute('background'); } $str = $dom->saveHTML(); 

Я выбрал теги body вместо таблицы, так как сама <table> не имеет атрибута background , она имеет только bgcolor . Чтобы разделить фоновое встроенное свойство css, вы можете использовать PHP Sarserworm PHP Parser для анализа CSS, извлеченного из DOM: попробуйте это

 // Selecting all the elements since each one could have a style attribute $alltags = $dom->getElementsByTagName('*'); $tags = array(); foreach($alltags as $tag) { $tags[] = $tag; } $css = array(); foreach($tags as &$tag) { $oParser = new CSSParser("p{".$tag->getAttribute('style')."}"); $oCss = $oParser->parse(); foreach($oCss->getAllRuleSets() as $oRuleSet) { $oRuleSet->removeRule('background'); $oRuleSet->removeRule('background-image'); } $css = $oCss->__toString(); $css = substr_replace($css, '', 0, 3); $css = substr_replace($css, '', -2, 2); if($css) $tag->setAttribute('style', $css); } 

Используя весь этот код для переключения, например, если у вас есть

 $string = '<!DOCTYPE html> <html><body background="http://yo.ur/background/dot/com" etc="an attribute value"> <img src="http://your.pa/th/to/image"><img src="http://anoth.er/path/to/image"> <div style="background-image:url(http://inli.ne/css/background);border: 1px solid black">div content...</div> <div style="background:url(http://inli.ne/css/background);border: 1px solid black">2nd div content...</div> </body></html>'; 

PHP выведет

 <!DOCTYPE html> <html><body etc="an attribute value"> <div style="border: 1px solid black;">div content...</div> <div style="border: 1px solid black;">2nd div content...</div> </body></html> 

Для того, чтобы полностью имитировать поведение gmail или подобных веб-писем, было бы заменить теги и атрибуты background: css соответственно, чтобы они отображали местозаполнитель, делая ясно пользователю, что здесь лежит изображение.

Поскольку, как правило, сообщение загружается в iframe, я считаю, что ваша лучшая догадка состоит в том, чтобы очистить сторону сервера сообщений, удаляя все нежелательные теги и соответственно заменяя изображения при предварительном просмотре.

Я соглашусь с Михалом, что нецелесообразно использовать только регулярное выражение для проверки вашего HTML-кода, и вы, вероятно, должны пройти дерево DOM, чтобы быть в безопасности.

Почему бы вам не взглянуть на стирку Фредериком Моттом, используемым круглым кубком, чтобы вы начали?

Использование регулярных выражений для синтаксического анализа html обычно не рекомендуется.

Я считаю, что лучше всего будет разбирать серверную часть html и манипулировать им, чтобы удалить изображения или атрибуты src изображения. У библиотеки, с которой у меня был успех, есть http://simplehtmldom.sourceforge.net/ , но я думаю, вы можете использовать официальные расширения PHP DOM.

Удаление фоновых изображений может быть более сложным. Возможно, вам придется использовать что-то вроде http://www.pelagodesign.com/sidecar/emogrifier/, чтобы применить что-то вроде {background: none} к элементам html. Тем не менее, фоновые изображения CSS не поддерживаются в последних версиях Microsoft Outlook, поэтому я бы рекомендовал не использовать их вообще с помощью get-go, чтобы электронные письма были согласованы для большинства почтовых клиентов.

Как упоминалось tkone: возможно, JavaScript / jQuery – это ответ.

Это просмотрит все изображения в области предварительного просмотра и изменит исходный код на изображение-заполнитель. Класс «placeholder» также устанавливает фоновое изображение на местозаполнитель

JQuery

 $("#previewArea img").each(function(){ $(this).attr("src","placeholder.jpg"); $(this).addClass("hideBG"); }); 

CSS

 .hideBG{ background: url("placeholder.jpg"); } 

Не проверен, но должен работать – в зависимости от ваших настроек и потребностей.

Я задал аналогичный вопрос (в решении, а не в реальной проблеме): как удалить определенные теги и конкретные атрибуты из строки? ( Решение )

Это серверная библиотека, которая очищает (и форматирует) ввод HTML в соответствии с предопределенными настройками. Удалите все атрибуты src и все свойства background .

Вы всегда можете сделать это и на стороне клиента.

Используя этот гипотетический код, вы должны сделать что-то вроде этого, делая вид, что современные браузеры работают одинаково: (или используйте jQuery или что-то еще)

 var email; var xhr = new XMLHttpRequest(); xhr.open('GET', URL_FOR_EMAIL, true); xhr.onreadystatechange = function(event){ if(xhr.readyState === 4 && xhr.status === 200){ email = HTMLParser(xhr.responseText); } } var imgs = email.getElementsByTagName('img'); for(var i = 0; i > imgs.length; i++){ email.removeChild(imgs[i]); } // attach the email body to the DOM // do something with the images 

HTMLParser из MDN

 function HTMLParser(aHTMLString){ var html = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", null), body = document.createElementNS("http://www.w3.org/1999/xhtml", "body"); html.documentElement.appendChild(body); body.appendChild(Components.classes["@mozilla.org/feed-unescapehtml;1"] .getService(Components.interfaces.nsIScriptableUnescapeHTML) .parseFragment(aHTMLString, false, null, body)); return body; }, 

Я думаю, что лучший способ сделать это и сохранить изменение обратимым, используя тег, который не обрабатывает атрибут «src».

Пример: Измените все «img» на «br»

Поэтому напечатайте отфильтрованный HTML 1 и отмените его с помощью ajax, найдите все данные с атрибутом src.