代码之家  ›  专栏  ›  技术社区  ›  Etienne Marais

如何使用PHP从HTML文档中删除所有javascript?

  •  5
  • Etienne Marais  · 技术社区  · 14 年前

    在我的电子邮件程序中,在发送电子邮件之前,我使用整洁来清理HTML。一个问题开始持续存在,如果我发送一封邮件,从Web上的一个URL获取HTML,那么文档中可能存在一些javascript。

    我想通过去掉所有的javascript、嵌入的、引用的和任何形式来清理这个HTML文档,从而使邮件只存在于HTML中。

    我想用PHP preg_replace() 为了从邮件中删除所有的javascript,我需要一些关于最好的regex的帮助,因为这不是我必须承认的最强点。

    5 回复  |  直到 10 年前
        1
  •  10
  •   Community CDub    7 年前
    echo preg_replace('/<script\b[^>]*>(.*?)<\/script>/is', "", $var); 
    

    如图所示 here .

        2
  •  4
  •   karim79    14 年前

    你可以用 strip_tags ,传递您想要的标签 允许 (whitelist)作为第二个参数,但这不会删除内联JS——它可能出现在onclick属性等中。

    echo strip_tags($html, '<p><a><small>');
    
        3
  •  2
  •   Lex    14 年前
        4
  •  2
  •   AbbasAli Hashemian    12 年前

    这(如下)并不能保证,但我试着做我的轻量解决方案,因为HTML净化器( http://htmlpurifier.org )对我的小目标来说是巨大的。 我的目标是防止XSS,而不是其他任何东西,因此XSS尝试的结果对于这段代码来说将是很多肮脏的事情,但我认为这是安全的:

    <?
    //href="javascript:
    //style="....expression
    //style="....behavior
    //<script
    //on*="
    $str = '
        asd 
        <a STyLE="asd; expression" hRef=" javascript:" onx="asd">asd</a>
        asd
        <code><a href="javascript:">asd</a></code>
        <scr<script></script>ipt ... >asd</script>
        <a style="hey:good boy;" href="javascript:">asd</a>';
    
    function stripteaser($str, $StripHTMLTags = true, $AllowableTags = NULL) {
        $str = explode('<code>', $str);
        $codes = array();
        if (count($str) > 1) {
            foreach ($str as $idx => $val) {
                $val = explode('</code>', $val);
                if (count($val) > 1) {
                    $uid = md5(uniqid(mt_rand(), true));
                    $codes[$uid] = htmlentities(array_shift($val), ENT_QUOTES, 'UTF-8');
                    $str[$idx] = "##$uid##" . implode('', $val);
                }
            }
        }
        $str = implode('', $str);
        while (stripos($str, '<script') !== false) {
            $str = str_ireplace('<script', '&lt;script', $str);
        }
        $rptjob = function(&$str, $regexp) {
                    while (preg_match($regexp, $str, $matches)) {
                        $str = str_ireplace($matches[0], htmlentities($matches[0], ENT_QUOTES, 'UTF-8'), $str);
                    }
                };
        $rptjob($str, '/href[\s\n\t]*=[\s\n\t]*[\"\'][\s\n\t]*(javascript:|data:)/i'); //href = "javascript:
        $rptjob($str, '/style[\s\n\t]*=[\s\n\t]*[\"][^\"]*expression/i'); //style = "...expression
        $rptjob($str, '/style[\s\n\t]*=[\s\n\t]*[\'][^\']*expression/i'); //style = '...expression
        $rptjob($str, '/style[\s\n\t]*=[\s\n\t]*[\"][^\"]*behavior/i'); //style = "...behavior
        $rptjob($str, '/style[\s\n\t]*=[\s\n\t]*[\'][^\']*behavior/i'); //style = '...behavior
        $rptjob($str, '/on\w+[\s\n\t]*=[\s\n\t]*[\"\']/i'); //onasd = "
        if ($StripHTMLTags)
            $str = strip_tags($str, $AllowableTags);
        foreach ($codes as $idx => $code) {
            $str = str_replace("##$idx##", $code, $str);
        }
        return $str;
    }
    
    echo stripteaser($str);
    exit;
    ?>
    

    D 在家里为这颗月亮写下了肮脏的密码…然而,这不是一个好工作(很多情况下需要几个CPU时间),但对于我的小目标来说,它比另一个巨大的组件(如HTML净化器)要好。

    结果将是:

    asd 
    <a STyLE=&quot;asd; expression" hRef=&quot; javascript:" onx=&quot;asd">asd</a>
    asd
    &lt;a href=&quot;javascript:&quot;&gt;asd&lt;/a&gt;
    <scri&lt;script></script>pt ... >asd</script>
    <a style="hey:good boy;" href=&quot;javascript:">asd</a>
    

    我对CSS表达式没有经验,但我知道在IE中使用JSVML来处理弯角的行为,所以很危险。 最后,没有也没有保证。

    希望对朋友有用 ;)

        5
  •  0
  •   pbs    10 年前

    我用过这个:

    //remove js,css,head.....
    static function cleanElements($html){
    
      $search = array (
             "'<script[^>]*?>.*?</script>'si",  //remove js
              "'<style[^>]*?>.*?</style>'si", //remove css 
    
          "'<head[^>]*?>.*?</head>'si", //remove head
         "'<link[^>]*?>.*?</link>'si", //remove link
         "'<object[^>]*?>.*?</object>'si"
                      ); 
            $replace = array ( 
                  "",
                                       "",
                  "",
                  "",
                  ""
                          );                 
      return preg_replace ($search, $replace, $html);
     }
    

    http://allenprogram.blogspot.pt/2012/04/php-remove-js-css-head-obj-elements.html

    删除除body和html之外的所有标记、脚本和样式,因此使用后,我使用strip_标记。