4

クライアント側とサーバー側でマークダウンを解析してサニタイズしようとしています。

  • クライアント側では、PageDownをマークダウン エディターとして使用します。これはまさに StackOverflow が使用するものであり、気の利いたプレビュー ボックスが付属しています。このプレビュー ボックスにはサニタイズされた html が表示されるため、<div>タグなどは削除されます。

  • サーバー側では、PegDownJSoupを使用してマークダウンの解析とサニタイズを行っています。

ただし、2 つの出力が同じではないケースを見つけています。例えば:

入力マークダウン: how are <div>tags</div> treated?

PageDown 出力: <p>how are tags treated?</p>

PegDown/JSoup 出力:

<p>how are </p>tags treated?
<p></p>

私は JSoup で特別なことをしているわけではありません。これが私のコードです:

public class Main {

    public static void main(String... args){

        PegDownProcessor pdp = new PegDownProcessor();

        String markdown = "how are <div>tags</div> treated?";

        String html = pdp.markdownToHtml(markdown);

        Whitelist whitelist = Whitelist.relaxed().removeTags("div");

        html = Jsoup.clean(html, whitelist);
        System.out.println(html);

        System.out.println("Done.");
    }
}

なぜこれが起こっているのか理解できますし、2 つの異なるシステムが 2 つの異なる出力を生成することに驚きはありません。私の質問は<div>、追加のタグを追加するのではなく、単にタグを削除するように JSoup をセットアップするにはどうすればよい<p>ですか?

私の最終的な目標は、サーバー側の解析/サニタイズで、クライアント側の解析/サニタイズと同様の結果が生成されるようにすることです。それを行うためのより良い方法があれば、私は提案を受け入れます。2 つの出力がまったく同じかどうかはあまり気にしませんが、余分な<p>タグなどはユーザーにとって非常に目立つので、この 1 つの大きな違いを排除しようとしています。

おまけの質問: PageDown が出力できる html タグと属性のリストはありますか?

編集: OWASP サニタイザーも使用してみましたが、非常によく似た結果が得られます。<div>タグは削除されますが、<p>タグは上記の方法で「修正」され、PageDown のサニタイザーとは異なる html になります。

4

1 に答える 1

2

余分な <p> タグを追加するのではなく、単に <div> タグを削除するように JSoup をセットアップするにはどうすればよいですか?

divHTML 5 仕様では、要素内での要素の使用が拒否されていpます。Jsoup はこれらの仕様を尊重します。これがp、最終的な html 文字列に 2 つの要素がある理由です。

なぜこれが起こるのかをよりよく理解するために、 がどのようにJsoup#clean機能するかを 3 つのステップで見てみましょう。

  1. ダーティ html を解析する
  2. 結果のツリーを調整して HTML 5 仕様を尊重する
  3. 拒否されたタグを削除

ステップ 2 では、最初の<p>タグが開始の直前で閉じられdivます。2 番目pも、この同じ手順で開始タグを取得します。Jsoup は、この段落の正当な内容がどこから始まるかを知らないため、この 2 番目の段落の内容を厳密な量 (つまり、何もない) に制限します。

ステップ 1 と 2 のアクションにより、HTML 5 仕様を満たす新しい HTML コードが作成されます。ステップ 3 で、divを取り外すことができます。

私の最終的な目標は、サーバー側の解析/サニタイズで、クライアント側の解析/サニタイズと同様の結果が生成されるようにすることです。

ここで見られるような他のケースを回避するには、クライアント側とサーバー側の両方で同じシステムを使用する必要があります。Pagedown は Javascript で記述されているため、サーバー側の Javascript エンジン内で実行することができます。

いくつか例を挙げると:

  • Nashorn (組み込み Java 8)
  • ライノ
  • V8

サンプルコード

Nashorn の使用例を以下に示します。

Caller.java

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval(new FileReader("script.js"));

Invocable invocable = (Invocable) engine;

Object result = invocable.invokeFunction("myFunction", "fooValue");

System.out.println(result);
System.out.println(result.getClass());

script.js

function myFunction(foo) {
   // ...
}

関連項目

于 2016-03-21T10:33:59.927 に答える