35

I have the following javascript code:

var html =  '<div class="col-lg-4 col-references" idreference="'+response+'"><span class="optionsRefer"><i class="glyphicon glyphicon-remove delRefer" style="color:red; cursor:pointer;" data-toggle="modal" data-target="#modalDel"></i><i class="glyphicon glyphicon-pencil editRefer" data-toggle="modal" data-target="#modalRefer" style="cursor:pointer;"></i></span><div id="contentRefer'+response+'">'+refer_summary+'</div><span id="nameRefer'+response+'">'+refer_name+'</span></div>';
$("#references").append(html);

When this code runs, the refer_summary variable actually contains a string which may contain HTML tags such as <b>, <i> etc., however, those tags are displayed on the page instead of rendering their behavior.

For example, on the page it would show <b> rather actually making the content bold.

How can I go about rendering the HTML tags when the value is appended?

In my Django template I use {% autoescape off %}{{content}}{% endautoescape %} so when I first load the page, the content is rendered correctly with bold etc. But how can I do the same thing when appending the html from javascript?

Thanks for the help!

1
  • 9
    Sounds like an XSS attack waiting to happen. Commented Jan 25, 2017 at 4:59

5 Answers 5

34

You can render HTML using document.write()

document.write('<html><body><h2>HTML</h2></body></html>');

But to append existing HTML string, you need to get the id of the node/tag under which you want to insert your HTML string.

There are two ways by which you can possibly achieve this:

  1. Using DOM -
var tag_id = document.getElementById('tagid');
var newNode = document.createElement('p');
newNode.appendChild(document.createTextNode('html string'));
  1. Using innerHTML -
var tag_id = document.getElementById('tagid');
tag_id.innerHTML = 'HTML string';
Sign up to request clarification or add additional context in comments.

2 Comments

The advantage of 2 is that no new element/dom as with write and 1 is created. Seems like a pure solution.
It should be added for clarity that in 1 and 2, any HTML markup contained in the 'html string' will in fact be parsed and converted to DOM nodes. So this is a way for growing the DOM, not just for inserting text strings.
9

Use $.parseHTML before the append html like as

var html =  '<div class="col-lg-4 col-references" idreference="'+response+'"><span class="optionsRefer"><i class="glyphicon glyphicon-remove delRefer" style="color:red; cursor:pointer;" data-toggle="modal" data-target="#modalDel"></i><i class="glyphicon glyphicon-pencil editRefer" data-toggle="modal" data-target="#modalRefer" style="cursor:pointer;"></i></span><div id="contentRefer'+response+'">'+refer_summary+'</div><span id="nameRefer'+response+'">'+refer_name+'</span></div>';
html = $.parseHTML( html);
$("#references").append(html);

1 Comment

The other approaches not worked for me in Outsystems, but this was perfect. Thanks.
5

You can use Javascript's document.createRange().createContextualFragment:

const frag = document.createRange().createContextualFragment('<div>One</div><div>Two</div>');
console.log(frag);

/*
  #document-fragment
    <div>One</div>
    <div>Two</div>
*/

https://davidwalsh.name/convert-html-stings-dom-nodes

Comments

3

If you want to do it in ReactJS, you can use "dangerouslySetInnerHTML" attribute, instead of "innerHTML" attribute.

As it allows the attackers to inject codes (XSS), it is named dangerous!

const myHtmlData = `
    <ul>
        <li>Item1<li>
        <li>Item2<li>
    </ul>`;
...
<div
    dangerouslySetInnerHTML={{
        __html: myHtmlData
}}>

Comments

0

You need to assign a particular div an id and then process/change UI in the specific div accordingly.

Given here is an excellent explanation.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.