Help us understand the problem. What is going on with this article?

Elmで生のHTMLをそのまま表示させる

More than 1 year has passed since last update.

ElmのXSS対策

Elmは非常に堅牢なアプリケーション開発に向いた親切でとても良くできた言語で、通常はXSS脆弱性を引き起こすことができないようになっています。
そのため、もちろん文字列として持っている生のHTMLを表示しようとして

import Html exposing (Html)


view : Model -> Html Msg
view model =
    div
        []
        [ text raw
        ]


raw : String
raw = """
    <div>
        こんにちはこんにちは
    </div>
    """

このようにしても、実際には

<div>
    &lt;div&gt;こんにちはこんにちは&lt;/div&gt;
</div>

こういうHTML相当のものに変換されます。

生のHTMLを埋め込みたくなったら

じゃあ、生のHTMLをそのままHTMLとして埋め込みたくなったらどうしたらいいのでしょうか?

まず大前提として、生のHTMLは生肉と同じくらい危険です。
生肉なんてヤギでも食べません。
(草食動物だから)

sakura.jpg

生HTMLを表示したくなったら自分の設計を疑うべきです。
全然関係ないけど、アニサキスとサニタイズってなんか似てるよね。

それでもやりたい

Elm 0.18 であれば危険🐐スクリプト芸を使うことができましたが、あまりにも危険なので0.19では禁止されました。
Elm 0.19ではあきらめるしかないのでしょうか?
(再三いいますが、普通はあきらめて設計を見直したほうが良いと思います)

なんと、裏技があるのです。
Elmのアプリ内でコードをハイライト表示するでも使ったelm-explorations/markdownを使います。
これはもともとマークダウンのテキストを Elmの Html型に変換する機能を提供しますが、その変換時に「HTMLをそのままサニタイズしないでHTML型に変換する」というオプションが用意されてます。
いぇーい。

sakura2.jpg

それがOptions型sanitizeっていうオプションです。
これを Falseにして toHtmlWith関数で Html型に変換してやれば良いんです。

先ほどの例はこうなります。

import Html exposing (Html)
import Markdown exposing (defaultOptions)


view : Model -> Html Msg
view model =
    Markdown.toHtmlWith
        { defaultOptions
            | sanitize = False
        }
        []
        raw


raw : String
raw = """
    <div>
        こんにちはこんにちは
    </div>
    """

わーい かんたん!

さくらちゃんにご飯をあげる
さくらちゃんをもっと見る
他の記事を見る
end.jpg

arowM
ヤギさんとして自由に生きてるよ さくらちゃんはアーティストだから世の理不尽には頭突きしちゃうよ フリーランスUXハッカー・プログラマー(Elm, Haskell)・技術翻訳・ヤギ語翻訳 ARoW代表 http://arow.info /気吹堂(出版)代表/UZUZ CXO http://github.com/arow
https://arow.info
arow-oss
もともと法人だったけど潰しちゃったよ c.f., https://qiita.com/arowM/items/9eddd10d531154cbc065
https://arow.info
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away