使用Javascript将大块HTML插入元素的最佳做法? [英] Best practice for inserting large chunks of HTML into elements with Javascript?

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

问题描述

我正在构建一个Web应用程序(使用原型),需要在DOM中添加大量的HTML。其中大多数是包含各种属性元素的行。



目前,我在变量中保留了空白的一行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);
}

现在这些工作都很好,但是最好的做法? / p>

当我更新页面上的代码时,我必须更新blankRow中的代码,因此插入的新元素是一样的。当我有40行HTML进入一个blankRow时,它变得吸吮,然后我也必须逃避它。



有更简单的方法吗?我正在考虑使用urlencoding,然后在插入之前对其进行解码,但这仍然意味着一个blankRow和大量的转义。



什么意思是一个eof函数et al。

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

这意味着没有转义,但仍然需要一个blankRow。



在这种情况下你做什么?



SOLVED



DOMBuilder在原型。没有其他库需要:

  $ 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>更多东西< / b> ')
);

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

查看我的解决方案这里 here

解决方案


是最佳做法吗?


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



您将纯文本内容和属性值放入HTML字符串中,您必须将 HTML编码。在PHP中,您必须在要进入HTML的字符串上调用 htmlspecialchars()。在JavaScript中,您不会获得内置的HTML转义功能,因此您必须自己制作。通过使用 s.replace(/& / g,'& amp;')替换(/< / g,'& lt; & quot;')


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


这是一个全新的级别的转义乱码,一个事件中的JavaScript字符串文字处理程序属性,您将不得不对字符串进行JS编码( \ -escaping ' \ 加上一些Unicode字符来完成)然后对结果进行HTML编码,否则字符串可以突破其字符串字面分隔符并注入任意JS代码在所有情况下避免内联事件处理程序属性,但特别是在模板中。



使用HTML字符串创建页面内容很有可能会导致转义错误并危及安全性的应用程序,使用类似DOM的方法,而不必担心这一点你似乎在使用jQuery,所以尝试使用jQuery 1.4元素创建快捷方式:

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

);或者,将文本中的空白行实际上保留为HTML,然后将其隐藏(<$ c(code)) $ c> display:none
)或者在开始时将其从文档中分离出来( removeChild 或者jQuery detach )。然后,当你想要一个新行时,克隆空行并进行所需的更改:

  var blankRow = $('# blankRow')分离(); 

...

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);
});

如果您必须从字符串模板创建内容,请确保您的模板功能默认情况下,并通过选择解析的内容中的节点来附加事件,以调用 click(function(){...})。或者使用事件委托(例如jQuery live())来处理事件,而不必在添加时绑定到新的节点。


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.

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

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