当前位置: 首页 > 知识库问答 >
问题:

在Vaadin中使用JSoup-不能禁用逃逸?

冉子石
2023-03-14

我试图修改Vaadin发送到浏览器的引导Javascript。以下是有关此问题的瓦丁论坛链接:https://vaadin.com/forum#!/Thread/4252604

Vaadin使用Jsoup,因此我使用JSoupAPI在Vaadin负载中找到正确的位置来修改Javascript。当我像这样使用Jsoup API时:

element.html(newHTML)

newHTML中的任何内容都会被转义。例如,如果newHTML是:

alert("hi");

然后调用JSoup API将导致:

alert("hi");

我想我可以通过如下操作禁用此Jsoup转义:

element.ownerDocument().outputSettings().escapeMode(...)

但是ownerDocument()是空的,所以我不认为这是一个选项。Jsoup是否有办法绕过这个限制,这样我就可以得到带有双引号(“)甚至开始/结束标记括号的Javascript(

共有2个答案

东门仲卿
2023-03-14

我的解决方案是子类TextNode并覆盖执行转义的方法。

package org.jsoup.nodes;

public class UnescapedTextNode extends TextNode
{
    public UnescapedTextNode( final String text, final String baseUri )
    {
        super( text, baseUri );
    }

    @Override
    void outerHtmlHead(
        final StringBuilder accum,
        final int depth,
        final Document.OutputSettings out )
    {
        //String html = Entities.escape( getWholeText(), out ); // Don't escape!
        String html = getWholeText();
        if ( out.prettyPrint() &&
             parent() instanceof Element &&
             !Element.preserveWhitespace( parent() ) )
        {
             html = normaliseWhitespace( html );
        }
        if ( out.prettyPrint() &&
             ( ( siblingIndex() == 0 &&
                 parentNode instanceof Element &&
                 ( (Element)parentNode ).tag().formatAsBlock() &&
                   !isBlank() ) ||
                 ( out.outline() &&
                   siblingNodes().size() > 0 &&
                   !isBlank() ) ) )
        {
            indent( accum, depth, out );
        }
        accum.append( html );
    }
}

这几乎是TextNode的逐字复制。outerHtmlHead()(最初由Jonathan Hedley编写)。我刚刚注释掉了转义部分。我就是这样使用它的:

// ... assuming head is of type Element and refers to the <head> of the document.
final String message = "Hello World!";
final String messageScript = "alert( \"" + message + "\" );";
final Element messageScriptEl = head.appendElement( "script" ).
    attr( "type", "text/javascript" );
final TextNode messageScriptTextNode = new UnescapedTextNode(
    messageScript,
    messageScriptEl.baseUri() );
messageScriptEl.appendChild( messageScriptTextNode );
// ... etc

进一步,调用文档。toString()文档。outerHtml()生成输出,其中的文本位于未经scape创建的脚本标记内。即:

<script type="text/javascript">alert( "Hello World!" );</script>

而不是:

<script type="text/javascript">alert( &quot;Hello World!&quot; );</script>

就像以前发生的那样。

我发现了两个“陷阱”:

>

  • 需要由加载原始jSoup库的相同的类加载器加载Unscape edTextNode类。这是因为在上面,我重写了一个包私有方法,这是JLS中规定的。(感谢杰夫·辛克莱的文章向我指出了这一点。中肯的一点是

    当且仅当下列任一条件为真时,类或接口D可以访问字段或方法R:

    • R是包私有的,由与D位于同一运行时包中的类声明

    它在访问控制(5.4.4)下的JVM规范中。

  • 谷梁晟
    2023-03-14

    显然,

    element.childNode(0).attr("data", html);
    

    如果元素是“脚本”元素,而html是Javascript源,就可以做到这一点。

     类似资料:
    • 问题内容: 我正在尝试在我的项目中使用它来发送电子邮件。当我单击时,a 启动并显示a。所有邮件一经发送,便不会消失。 这是我的代码: 如何控制分隔符的可见性? 问题答案: 要从后台线程更新UI元素,您必须激活推送或轮询。 该文档可以在vaadin书中找到。 https://vaadin.com/de/book/vaadin7/-/page/advanced.push.html 除了启用推送之外,还

    • 我目前正在尝试使用Vaadin.Spring的ViewAccessControl接口,如本教程最后一段所述。 但是在实现isAccessGranted方法时,我会得到以下错误:

    • 我已经重建了vaadin webapp,并删除了任何Spring功能。我的网络应用程序现在是非基于Spring的应用程序的GreetService入门下载。 该应用程序在tomcat 9.0应用服务器上运行,在tomcat_HOME/conf/web中具有以下配置。用于目录列表的xml。 申请中没有其他web.xml。 我包括一个空的index.html在两个文件夹亚历杭德罗建议,只是把一个简单的

    • 我想选择要上传的文件,然后让用户做一些其他事情,然后当他单击提交按钮时,我想执行实际上传。 如何在不使用上载按钮的情况下执行/启动上载?

    • 对于Vaadin10和Vaadin12我得到了相同的结果。spring版本是2.1.2 我期待以下结果 我调用localhost:xxx/=>浏览器询问用户名/密码 我调用localhost:xxx/logout=>浏览器不问密码!