我正在用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。