我正在创建一个论坛,我只希望在该论坛上显示img标签,并希望所有其他标签安全地转义, 但不 被删除。除了从头开始创建函数之外,完成此任务的最佳方法是什么?
我尝试使用HTML Purifier,但它会剥离所有不需要的标签,而仅保留所需的标签。此外,我尝试了其他功能,例如strip_tags和htmlentities
以及blaede({{ }}
)中使用的转义运算符,但这些功能将剥离不需要的标签(我希望将其转义)或转义所有标签(我也不想要,因为我想保留<img>
和<br>
标签。我看到了其他类似的问题,但不幸的是,它们都没有真正帮助过我。>
到目前为止,我正在使用的是:
$post->content = Purifier::clean($request->content);
暂时删除不需要的标签以防止XSS。
我希望用户插入的数据显示如下:
Hi all
<script>alert('hi all')</script>
<img src='sun.png'/>
现在显示以下内容
Hi all
hi all
<img src='sun.png'/>
更新:
我的问题与被标记的问题重复了 。希望主持人能够解决这个问题。
答案 0 :(得分:1)
您需要先用一些字符串占位符替换<img>
和<br>
标签,再用htmlentities()
进行转义,然后恢复原始的<img>
和<br>
标签背部。这是解决问题的方法:
$string = "Hi<br> all<script>alert('hi all')</script><img src='sun.png'/>";
// First we cleanup our string from possible pre-existing placeholders (like $$0, $$1 etc).
$string = preg_replace('~\$\$[0-9]+~', '', $string);
// Then we replace all <img> and <br> tags with such placeholders while
// storing them into $placeholders array.
$placeholders = [];
$i = 0;
$string = preg_replace_callback('~(<img[^>]*>(</img>)?|<br[^>]*>)~', function ($matches) use (&$placeholders, &$i) {
$key = '$$'.$i++;
$placeholders[$key] = $matches[0];
return $key;
}, $string);
// Our string no longer has <img> and <br> tags so we can safely escape
// the rest.
$string = htmlentities($string);
// Lastly we restore <img> and <br> tags by swapping them back instead of their respective placeholders.
foreach ($placeholders as $key => $placeholder) {
$string = str_replace($key, $placeholder, $string);
}
echo $string;
此代码将产生结果:
Hi<br> all<script>alert('hi all')</script><img src='sun.png'/>
此解决方案在很大程度上依赖于使用正则表达式,因此我强烈建议您学习此主题,以防日后需要调整代码。