webentwicklung-frage-antwort-db.com.de

skripttag aus HTML-Inhalten entfernen

Ich verwende HTML Purifier (http://htmlpurifier.org/)

Ich möchte nur <script>-Tags nur entfernen. Ich möchte keine Inline-Formatierungen oder andere Dinge entfernen.

Wie kann ich das erreichen?

Eine weitere Sache, es gibt eine andere Möglichkeit, Skript-Tags aus HTML zu entfernen

51
I-M-JM

Da diese Frage mit Regex ​​markiert ist, werde ich in dieser Situation mit der Lösung des armen Mannes antworten:

$html = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $html);

Reguläre Ausdrücke sind jedoch nicht für das Analysieren von HTML/XML gedacht. Auch wenn Sie den Ausdruck perfect schreiben, wird der Ausdruck eventuell beschädigt. Es lohnt sich jedoch nicht. In manchen Fällen ist es jedoch hilfreich, einige Markup-Elemente schnell zu korrigieren Vergessen Sie bei schnellen Korrekturen security. Verwenden Sie Regex nur für Inhalte/Markups, denen Sie vertrauen. 

Denken Sie daran, dass alle Benutzereingaben als nicht sicher betrachtet werden sollten. 

Bessere Lösung wäre hier die Verwendung von DOMDocument, das für diesen Zweck entwickelt wurde. Hier ist ein Ausschnitt, der zeigt, wie einfach, sauber (im Vergleich zu Regex), (fast) zuverlässig und (fast) sicher das zu tun ist gleich:

<?php

$html = <<<HTML
...
HTML;

$dom = new DOMDocument();

$dom->loadHTML($html);

$script = $dom->getElementsByTagName('script');

$remove = [];
foreach($script as $item)
{
  $remove[] = $item;
}

foreach ($remove as $item)
{
  $item->parentNode->removeChild($item); 
}

$html = $dom->saveHTML();

Ich habe den HTML-Code absichtlich entfernt, da auch dies bork kann.

115

Verwenden Sie den Parser PHP DOMDocument .

$doc = new DOMDocument();

// load the HTML string we want to strip
$doc->loadHTML($html);

// get all the script tags
$script_tags = $doc->getElementsByTagName('script');

$length = $script_tags->length;

// for each tag, remove it from the DOM
for ($i = 0; $i < $length; $i++) {
  $script_tags->item($i)->parentNode->removeChild($script_tags->item($i));
}

// get the HTML string back
$no_script_html_string = $doc->saveHTML();

Dies hat mich mit dem folgenden HTML-Dokument bearbeitet:

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>
            hey
        </title>
        <script>
            alert("hello");
        </script>
    </head>
    <body>
        hey
    </body>
</html>

Beachten Sie, dass für den DOMDocument-Parser PHP 5 oder höher erforderlich ist.

36
Alex
$html = <<<HTML
...
HTML;
$dom = new DOMDocument();
$dom->loadHTML($html);
$tags_to_remove = array('script','style','iframe','link');
foreach($tags_to_remove as $tag){
    $element = $dom->getElementsByTagName($tag);
    foreach($element  as $item){
        $item->parentNode->removeChild($item);
    }
}
$html = $dom->saveHTML();
2
prasanthnv

Ich hatte mit dieser Frage zu kämpfen. Ich habe festgestellt, dass Sie wirklich nur eine Funktion benötigen. explodieren ('>', $ html); Der gemeinsame Nenner eines Tags ist <und>. Danach sind es normalerweise Anführungszeichen ("). Sie können so einfach Informationen extrahieren, wenn Sie den gemeinsamen Nenner gefunden haben.

$html = file_get_contents('http://some_page.html');

$h = explode('>', $html);

foreach($h as $k => $v){

    $v = trim($v);//clean it up a bit

    if(preg_match('/^(<script[.*]*)/ius', $v)){//my regex here might be questionable

        $counter = $k;//match opening tag and start counter for backtrace

        }elseif(preg_match('/([.*]*<\/script$)/ius', $v)){//but it gets the job done

            $script_length = $k - $counter;

            $counter = 0;

            for($i = $script_length; $i >= 0; $i--){
                $h[$k-$i] = '';//backtrace and clear everything in between
                }
            }           
        }
for($i = 0; $i <= count($h); $i++){
    if($h[$i] != ''){
    $ht[$i] = $h[$i];//clean out the blanks so when we implode it works right.
        }
    }
$html = implode('>', $ht);//all scripts stripped.


echo $html;

Ich sehe, dass dies nur für Skript-Tags funktioniert, da Sie niemals verschachtelte Skript-Tags haben werden. Natürlich können Sie problemlos mehr Code hinzufügen, der dieselben verschachtelten Tags prüft und sammelt.

Ich nenne es Akkordeon-Codierung. implode (); explodieren (); sind die einfachsten Möglichkeiten, um Ihre Logik zum Fließen zu bringen, wenn Sie einen gemeinsamen Nenner haben.

1

verwenden Sie die Funktion str_replace, um sie durch Leerzeichen oder etwas zu ersetzen

$query = '<script>console.log("I should be banned")</script>';

$badChar = array('<script>','</script>');
$query = str_replace($badChar, '', $query);

echo $query; 
//this echoes console.log("I should be banned")

?>

0

Ein einfacher Weg durch Manipulation der Zeichenfolge.

$str = stripStr($str, '<script', '</script>');

function stripStr($str, $ini, $fin)
{
    while(($pos = mb_stripos($str, $ini)) !== false)
    {
        $aux = mb_substr($str, $pos + mb_strlen($ini));
        $str = mb_substr($str, 0, $pos).mb_substr($aux, mb_stripos($aux, $fin) + mb_strlen($fin));
    }

    return $str;
}
0

Dies ist eine vereinfachte Variante der Antwort von Dejan Marjanovic:

function removeTags($html, $tag) {
    $dom = new DOMDocument();
    $dom->loadHTML($html);
    foreach (iterator_to_array($dom->getElementsByTagName($tag)) as $item) {
        $item->parentNode->removeChild($item);
    }
    return $dom->saveHTML();
}

Kann verwendet werden, um alle Arten von Tags zu entfernen, einschließlich <script>:

$scriptlessHtml = removeTags($html, 'script');
0
mae

Ein Beispiel, das die Antwort von ctf0 modifiziert. Das sollte preg_replace nur einmal ausführen, aber auch auf Fehler und Blockcode für den Schrägstrich prüfen. 

$str = '<script> var a - 1; <&#47;script>'; 

$pattern = '/(script.*?(?:\/|&#47;|&#x0002F;)script)/ius';
$replace = preg_replace($pattern, '', $str); 
return ($replace !== null)? $replace : $str;  

Wenn Sie PHP 7 verwenden, können Sie den Nullkoaleszenzoperator verwenden, um ihn noch weiter zu vereinfachen. 

$pattern = '/(script.*?(?:\/|&#47;|&#x0002F;)script)/ius'; 
return (preg_replace($pattern, '', $str) ?? $str); 
0
tech-e

Kürzer:

$html = preg_replace("/<script.*?\/script>/s", "", $html);

Wenn man Regex macht, kann es passieren, dass etwas schief geht. Deshalb ist es sicherer, dies so zu tun:

$html = preg_replace("/<script.*?\/script>/s", "", $html) ? : $html;

Wenn der "Unfall" passiert, erhalten wir also das ursprüngliche $ html anstelle eines leeren Strings.

0
Binh WPO

Ich würde BeautifulSoup verwenden, wenn es verfügbar ist. Macht so etwas sehr einfach.

Nicht Versuchen Sie es mit Regexps. Auf diesem Weg liegt der Wahnsinn.

0
Malvolio
  • dies ist eine Zusammenführung von ClandestineCoder und Binh WPO.

das Problem mit den Skript-Tag-Pfeilen ist, dass sie mehrere Varianten haben können 

ex. (<= &lt; = &amp;lt;) & (> = &gt; = &amp;gt;)

anstatt ein Pattern-Array mit einer Bazillion-Variante zu erstellen, wäre imho eine bessere Lösung

return preg_replace('/script.*?\/script/ius', '', $text)
       ? preg_replace('/script.*?\/script/ius', '', $text)
       : $text;

dadurch wird alles entfernt, das wie script.../script aussieht, unabhängig vom Pfeilcode/der Variante. Sie können es hier testen. https://regex101.com/r/lK6vS8/1

0
ctf0