从 html 中删除图片的方式与 Gmail 对未启用图片的电子邮件所做的相同


Remove images from html the same as gmail would do for emails without images enabled

我正在用PHP编写一个简单的HTML电子邮件设计编辑器,并展示了一个演示。

我认为向用户展示它在关闭图像的电子邮件客户端(例如 gmail)中的外观也非常有用。

我最好的方法是什么?有人知道如何在gmail/hotmail等中完成此操作吗?

我是否简单地删除img -> src并使用 reg 表达式css background: url

我想从以下位置删除背景部分: background="url"用于表格和 background-image:url(url);使用的内联 CSS

我发现这个问题也有同样的想法,尽管我想从HTML文本中删除img和backrgound图像。

或者也可以修改此代码以处理背景图像?

我还建议使用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();

我选择了正文标签而不是表格,因为<table>本身没有background属性,它只有bgcolor。要去除后台内联 css 属性,您可以使用 sabberworm 的 PHP CSS 解析器要解析从 DOM 检索到的 CSS:试试这个

// 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或类似网络邮件的行为,需要相应地替换标签和背景:css属性,以便它们显示占位符,向用户清楚地表明这里有一个图像。

由于通常消息是在 iframe 中加载的,我相信您最好的猜测是清理消息服务器端,删除所有不需要的标签并在预览时相应地替换图像。

我同意 Michal 的观点,即仅使用正则表达式来验证您的 HTML 是不明智的,为了安全起见,您可能应该遍历 DOM 树。

你为什么不看看 rederic Motte 的 washtml 被 roundcube 用来让你入门呢?

通常不建议使用正则表达式来解析 html。

我认为更好的方法是解析 html 服务器端,并对其进行操作以删除图像或图像 src 属性。我成功的一个库是 http://simplehtmldom.sourceforge.net/,但我认为你可以使用官方的 PHP DOM 扩展。

删除背景图像可能更棘手。您可能必须使用 http://www.pelagodesign.com/sidecar/emogrifier/之类的东西才能将类似 {background: none} 的东西应用于 html 元素。但是,最新版本的Microsoft Outlook不支持CSS背景图像,因此我建议从一开始就不要使用它们,以使大多数电子邮件客户端的电子邮件保持一致。

就像tkone提到的:也许JavaScript/jQuery就是答案。

这将查看预览区域中的所有图像,并将源更改为占位符图像。"占位符"类也将背景图像设置为占位符

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

来自 MDN 的 HTMLParser

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 1st 并使用 ajax 将其反转,搜索所有带有 src 属性的 br。