java - Android HtmlCompat.fromHtml() 创建 Spanned 后如何停止 EditText 显示 javascript

标签 java android android-edittext

我的 View 中有一个 EditText。我正在使用HtmlCompat.fromHtml()在此 EditText 中显示电子邮件的内容,以便可以查看和编辑。如果 html 包含任何 JavaScript,那么它将在生成的 Spanned 中呈现。

如果我有以下(示例)代码:

String htmlString = "<html>\n" +
    "\n" +
    "<head>\n" +
    "    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n" +
    "    <script type=\"text/javascript\">\n" +
    "        alert(\"This should not appear in the EditText\");\n" +
    "    </script>\n" +
    "</head>\n" +
    "\n" +
    "<body style=\"margin: 0;padding: 0;box-sizing: border-box;-webkit-font-smoothing: antialiased;-webkit-text-size-adjust: none;width: 100% !important;height: 100% !important;line-height: 1.6;margin-top: 0 !important;margin-left: 0 !important;margin-right: 0 !important\" class=\"\">\n" +
    "    <div dir=\"auto\">Technician booked for tomorrow morning\n" +
    "        <br>\n" +
    "        <br>\n" +
    "    </div>\n" +
    "    <div dir=\"auto\">\n" +
    "        <a href=\"http://www.bluemail.me/r?b=15726\"></a>\n" +
    "    </div>\n" +
    "</body>\n" +
    "\n" +
    "</html>";

emailTextView.setText(HtmlCompat.fromHtml(htmlString, HtmlCompat.FROM_HTML_MODE_COMPACT));

然后EditText显示<script type=\"text/javascript\">alert(\"This should not appear in the EditText\");</script>的内容我原以为它会被删除/隐藏。但我得到:

screen shot showing the issue

有什么方法可以阻止这种情况,或者有其他方法可以在 EditText 中呈现电子邮件中的 html 进行编辑吗?我知道 Gmail 可以在 Android 上执行此操作,但我看不到它是如何完成的?

最佳答案

<script>whatever</script>正在被剥离,留下“无论什么”。这是 HtmlCompat.fromHtml() 对于它无法识别的标签的默认行为。在调用 HtmlCompat.fromHtml() 之前,您需要从字符串中去除问题标签和关联文本。您可以使用直接字符串匹配或正则表达式来完成此操作。

对于 Java:

String newString =  mHtmlString.replaceAll("(?is)<script.*?</script>","")

对于 Kotlin:

val newString = mHtmlString.replace(Regex("(?is)<script.*?</script>"), "")

第二种方法是使用您可以在调用 fromHtml(String, int, ImageGetter, TagHandler) 时指定的标记处理程序。

override fun handleTag(
    opening: Boolean,
    tag: String,
    output: Editable,
    xmlReader: XMLReader?
) {
    class DeleteSpan

    if (!tag.equals("script", true)) {
        return
    }
    if (opening) {
        output.setSpan(DeleteSpan(), output.length, output.length, Spannable.SPAN_MARK_POINT)
    } else {
        val spans = output.getSpans(0, output.length, DeleteSpan::class.java)
        val lastSpan = spans[spans.size - 1]
        output.apply {
            delete(getSpanStart(lastSpan), getSpanEnd(lastSpan))
            removeSpan(lastSpan)
        }
    }
}

第二种方法只是从输出中删除脚本标记的内容。

关于java - Android HtmlCompat.fromHtml() 创建 Spanned 后如何停止 EditText 显示 javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60199858/

相关文章:

java - 在我的 hibernate 应用程序中,没有获取 session 但没有抛出任何错误

android - RecyclerView 滚动问题中的多行 EditText

android - 防止背景调整大小并防止在 Activity 开始时自动聚焦

java - 出现致命异常无法理解原因

Android 6 Nexus 5 USB 连接问题

android - 从资源中获取 android 字符串数组中的数据

android - recyclerview 内的多行编辑文本未正确滚动

java - Log42 异步记录器在应用程序突然关闭时如何表现?

java - JFreeChart 中的多线程

java - 以编程方式关闭 Android 设备上的 USB 存储