Elm虚拟DOM不允许script节点,如何集成Telegram登录组件?
在ELM中正确集成Telegram登录组件
ELM的核心安全机制会自动过滤虚拟DOM中的<script>标签(防止XSS攻击),所以你直接用node "script"创建的节点会被替换成<p>标签。要解决这个问题,需要通过Port在JavaScript端动态插入script标签,具体步骤如下:
步骤1:在ELM中定义Port
Port是ELM与JavaScript通信的桥梁,我们用它触发JS端插入Telegram登录组件的逻辑:
port module Main exposing (..) import Html exposing (Html) -- 定义Port,通知JS插入Telegram登录组件 port insertTelegramLogin : () -> Cmd msg type alias Model = {} init : () -> (Model, Cmd Msg) init _ = -- 页面加载时自动触发插入(也可以通过按钮点击等事件触发) ({}, insertTelegramLogin ()) type Msg = NoOp update : Msg -> Model -> (Model, Cmd Msg) update msg model = (model, Cmd.none) view : Model -> Html Msg view model = -- 这里可以放你的页面内容,Telegram组件会被JS插入到DOM中 Html.div [] [] main = Html.program { init = init , view = view , update = update , subscriptions = \_ -> Sub.none }
步骤2:在JavaScript端实现Port回调
在挂载ELM应用的HTML文件中,添加JS代码处理Port消息,动态创建并插入script标签:
var app = Elm.Main.fullscreen(); app.ports.insertTelegramLogin.subscribe(function() { // 避免重复加载组件 if (document.querySelector('script[src="https://telegram.org/js/telegram-widget.js?21"]')) { return; } const script = document.createElement('script'); script.async = true; script.src = 'https://telegram.org/js/telegram-widget.js?21'; script.setAttribute('data-telegram-login', 'botname'); script.setAttribute('data-onauth', 'onTelegramAuth(user)'); // 将组件插入到指定位置(比如body末尾) document.body.appendChild(script); }); // 全局回调函数,处理Telegram登录成功后的逻辑 function onTelegramAuth(user) { console.log('Telegram登录用户信息:', user); // 可选:通过Port将用户信息传回ELM // app.ports.receiveTelegramUser.send(user); }
注意事项
- 修正你代码中的URL拼写错误:
telegrami.org应该改为telegram.org,否则资源无法正确加载。 - 如果需要将登录后的用户信息传回ELM,可以再定义一个Port来接收JS发送的数据。
内容的提问来源于stack exchange,提问作者uben
相关产品推荐
相关产品推荐

