插入HTML大块与JavaScript元素的最佳实践? [英] Best practice for inserting large chunks of HTML into elements with Javascript?

查看:156
本文介绍了插入HTML大块与JavaScript元素的最佳实践?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立一个Web应用程序(使用原型),需要增加HTML大块到DOM。其中大部分是包含与属性的所有方式的元素行。

目前我把HTML的空白行中的变量和

  VAR blankRow ='< TR>< TD>
    +'&所述; A HREF ={LINK}的onclick =someFunc(\'{STRING} \');> {WORD}&所述; / a取代;'
    +'< / TD>< / TR>';

功能的insertRow(O){
    NEWROW = blankRow
        .SUB({LINK}',o.link)
        .SUB({STRING}',o.string)
        .SUB({WORD}',o.word);
    $('tbodyElem')INSERT(NEWROW)。
}
 

现在的作品都很好,花花公子,但它是最好的做法?

我必须更新code在blankRow当我更新页面上的code,所以要插入的新元素是相同的。它得到苏茨基时,我有一个像40行的HTML走了blankRow,然后我必须逃离这一点。

有没有更简单的方法?我在想URL编码的,然后将其插入之前解码但这仍然意味着逃避的blankRow和地段。

什么是平均值将是一个EOF函数一拉PHP等。

  $ blankRow =<<< EOF
文本
文本
EOF;
 

这将意味着无法逃避,但它仍然需要一个blankRow。

你怎么在这种情况下怎么办?

解决

最终使用在原型DOMBuilder。是不需要其他库:

  $ W('一个div p跨度IMG表THEAD TD届TR TBODY TFOOT输入')。每个(函数(五){
        窗口['$'+ E] =功能(){
            返回新元素(即参数[0]);
        }
});

NEWPART = $格({ID:'分区-4'})
    .insert($ P()
        .insert('< B>东西< / B>')
    )
    .insert($ P({
        ID:A-P'})
        .insert('< B>更多的东西< / B>')
    );

$('parentDiv')INSERT(NEWPART)。
 

请参阅我的解决方案这里或的这里

解决方案
  

这是最好的做法?

没有。其实你有导致错误的HTML注入问题,并在注入字符串可能包含用户提交的内容在最坏的情况下,XSS安全漏洞。

当你把纯文本内容和属性值转换为HTML字符串,你的必须的HTML-CN code它们。在PHP中,你必须调用用htmlspecialchars()上串进入HTML做到这一点。在JavaScript中,你没有得到一个内置的HTML转义功能,所以你必须做你自己的,如。通过使用 s.replace(/&安培/克,'&放大器;放大器;')。更换(/< /克,'和; LT;')取代(//克,。 &功放; QUOT;。')的字符串进入的HTML

  

的onclick =someFunc(\'{STRING} \');

这是逃避乱一个全新的水平。在JavaScript字符串事件处理程序属性中,你将不得不JS-CN code中的字符串( \ -escaping \ 加上完备的几个统一code字符)的的那么HTML-CN code结果。否则,字符串可以突破其字符串文字分隔符,并注入任意JS code。避免在所有情况下的内联的事件处理程序的属性,但特别是在模板

创建页面内容的HTML字符串很烂。你很可能使逃避错误,并危及您的应用程序的安全性。使用DOM的方法,而不是,你不担心这一点。你似乎是使用jQuery,所以尝试了jQuery 1.4元素创建的快捷方式:

  $('< TR>')追加(。
    $('< TD>)。追加(
        $('&其中a取代;',{
            HREF:o.link,
            文字:o.word,
            的onclick:函数(){
                someFunc(o.string);
            }
        })
    )
);
 

或者,让您的空白行实际上是文档HTML里面,但随后将其隐藏(显示:无)或从文件中分离它的启动时间( removeChild之或jQuery的分离)。然后,当你想要一个新行,克隆的空白行,让你需要的变化:

  VAR blankRow = $('#blankRow')分离()。

    ...

变种NEWROW = blankRow.clone();
变种链路= newRow.find('TD>一种');
link.attr(HREF:o.link);
link.text(o.word);
link.click(函数(){
    someFunc(o.string);
});
 

如果您必须创建字符串模板的内容,确保您的模板功能的HTML逃脱每更换默认情况下,通过选择被分析的内容里面节点调用将事件附加点击(函数(){.. })上。或使用事件代理(如jQuery的生活())来处理事件,而无需添加时要绑定到新的节点。

I'm building a web application (using prototype) that requires the addition of large chunks of HTML into the DOM. Most of these are rows that contain elements with all manner of attributes.

Currently I keep a blank row of HTML in a variable and

var blankRow = '<tr><td>'
    +'<a href="{LINK}" onclick="someFunc(\'{STRING}\');">{WORD}</a>'
    +'</td></tr>';

function insertRow(o) {
    newRow = blankRow
        .sub('{LINK}',o.link)
        .sub('{STRING}',o.string)
        .sub('{WORD}',o.word);
    $('tbodyElem').insert( newRow );
}

Now that works all well and dandy, but is it the best practice?

I have to update the code in the blankRow when I update code on the page, so the new elements being inserted are the same. It gets sucky when I have like 40 lines of HTML to go in a blankRow and then I have to escape it too.

Is there an easier way? I was thinking of urlencoding and then decoding it before insertion but that would still mean a blankRow and lots of escaping.

What would be mean would be a eof function a la PHP et al.

$blankRow = <<<EOF
text
text
EOF;

That would mean no escaping but it would still need a blankRow.

What do you do in this situation?

SOLVED

Ended up using a DOMBuilder in prototype. No other libraries were needed:

$w('a div p span img table thead td th tr tbody tfoot input').each(function(e) {
        window['$' + e] = function() {
            return new Element(e, arguments[0]);
        }
});

newPart = $div({id: 'partition-4'})
    .insert( $p()
        .insert('<b>Stuff</b>')
    )
    .insert( $p({
        id: 'a-p'})
        .insert('<b>More stuff</b>')
    );

$('parentDiv').insert(newPart);

See my solution here or here.

解决方案

is it the best practice?

No. In fact you've got HTML-injection problems leading to bugs, and in the worst case where the injected strings may contain user-submitted content, XSS security holes.

When you put plain text content and attribute values into an HTML string, you must HTML-encode them. In PHP, you have to call htmlspecialchars() on strings going into HTML to do it. In JavaScript, you don't get a built-in HTML-escaping function, so you have to make your own, eg. by using s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/"/g, '&quot;') on the string going into the HTML.

onclick="someFunc(\'{STRING}\');"

That's a whole new level of escaping mess. In a JavaScript string literal inside an event handler attribute, you would have to JS-encode the string (\-escaping ' and \ plus a few Unicode characters for completeness) and then HTML-encode the results. Otherwise the string can break out of its string-literal delimiter and inject arbitrary JS code. Avoid inline event handler attributes in all cases, but especially in templating.

Creating page content with HTML strings sucks. You are very likely to make escaping errors and compromise the security of your application. Use DOM-like methods instead and you don't have to worry about this. You seem to be using jQuery, so try the jQuery 1.4 element creation shortcuts:

$('<tr>').append(
    $('<td>').append(
        $('<a>', {
            href: o.link,
            text: o.word,
            onclick: function() {
                someFunc(o.string);
            }
        })
    )
);

or, keep your blank row actually inside the document as HTML, but then hide it (display: none) or detach it from the document at start time (removeChild or jQuery detach). Then when you want a new row, clone the blank row and make the changes you need:

var blankRow= $('#blankRow').detach();

    ...

var newRow= blankRow.clone();
var link= newRow.find('td>a');
link.attr('href': o.link);
link.text(o.word);
link.click(function() {
    someFunc(o.string);
});

If you must create content from string templates, ensure your templating function HTML-escapes every replacement by default, and attach events by selecting nodes inside the parsed content to call click(function() { ... }) on. Or use event delegation (eg. jQuery live()) to handle events without having to bind to new nodes when added.

这篇关于插入HTML大块与JavaScript元素的最佳实践?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆