Displaying uninterpreted HTML code into a html iframe - javascript

I want to display a text with CR and tabs (let's say the code is into a var shtml) into a iframe without losing the ASCII characters.
<!--var shtml-->
<HEAD>
</HEAD>
<BODY style="FONT-SIZE: 12.5pt">
mmm
</BODY>
My iframe
<iframe rows="5" cols="60" id="tahtml">
</iframe >
My JS
document.getElementById('tahtml').textContent = shtml; //innerText = shtml;
If I use .innerText then the code(shtml) is interpreted in Firefox. If I use .textContent the code(shtml) is displayed wihtout the ASCII characters. the jQuery .text() dose the same as .textContent.

Just like an <input>, a <textarea>'s DOM interface (HTMLTextAreaElement) has a value property, it looks like you want to set this property to shtml.
document.getElementById('tahtml').value = shtml;
Demo
For an <iframe> make the MIME for the page loaded inside it text/plain. This can be done by, for example, fetching an empty .txt or setting the src to data:text/pain,. Then you can do the following
// don't collapse whitespace, only needed to be done once
ifrmDoc.documentElement.style.whiteSpace = 'pre';
// set text
ifrmDoc.documentElement.innerHTML = shtml;
Where
var ifrm = document.getElementById('tahtml'),
ifrmDoc = ifrm.contentDocument || ifrm.contentWindow.document;
Of course, you could also do it by
writing the whole thing as a dataURI and pass it as the src
ifrm.src = 'data:text/pain,' + window.encodeURIComponent(shtml);
appending your text using by using DOM methods and text nodes
ifrmDoc.body.appendChild(ifrmDoc.createTextNode(shtml))
(this would still require whiteSpace: pre;)
making a <textarea> or <pre> in your <iframe>, into which you put shtml as value or a text node, respectively.

Related

How to work around setting innerHTML causing escape sequences to expand?

I am trying to avoid a cross-site scripting vulnerability on my server. Before any user-inputted string is embedded within HTML or sent to client-side javascript code it is escaped ('<' replaced with '<', '&' replaced with '&', etc.) When embedding into HTML this works mostly fine; the HTML code produced does not contain any HTML elements inside the user-provided string. However, when the client-side javascript inserts HTML into the document, the escape sequences get expanded back into their special characters, which can result in user-inputted tags appearing in the document HTML. Here's approximately what I'm doing, javascript client-side:
// response_data received from XMLHttpRequest and parsed as JSON
var s = "";
for (var i = 0; i < response_data.length; ++i) {
s += "<p>";
s += response_data[i];
s += "</p>";
}
console.log(s);
elem.innerHTML = s;
Suppose the user inputted the string "abcde <script>alert("Hello!");</script>" earlier. Then response_data could be ["abcde <script>alert("Hello!");</script>"]. The print to console shows s to be "<p>abcde <script>alert("Hello!");</script></p>". However, when I assign elem.innerHTML, I can see in Inspect Element that the inner HTML of the element is actually <p>abcde <script>alert("Hello!");</script></p>! I don't think it executed, probably because of some browser security features regarding script tags within p tags, but it's obviously not very good. How do I work around this?
Code snippet (run and inspect element over the text created, it shows a script tag within the p tag):
var div_elem = document.querySelector("div");
div_elem.innerHTML = "<p><script>alert("Hello!");</script></p>";
<html>
<head></head>
<body>
<div></div>
</body>
</html>
Use innerText, it's like innerHTML but it's treated as pure text and won't decode the HTML entities.
Edit:
Set innerHTML to the p tags, then set the actual text using innerText on the tag
elem.innerHTML = "<p></p>";
elem.childNodes[0].innerText = s;

How to use regex to replace text between tags

I'd like to replace some text in a string that represents a div tag that may or may not also include style and class attributes. For example,
var s = "<div style='xxx' class='xxx'>replaceThisText<div>
If it were just the tag, I believe I could just do this:
str = str.replace(/<div>[\s\S]*?<\/div>/, '<div>' + newText+ '<\/div>');
But how do I take the attributes into account?
Generate a temporary element with your string as HTML content then get the div within it to update content after updating the content get back the HTML of temporary element.
var s = "<div style='xxx' class='xxx'>replaceThisText<div>";
// create a temporary div element
var temp = document.createElement('div');
// set content as string
temp.innerHTML = s;
// get div within the temporary element
// and update the content within the div
temp.querySelector('div').innerHTML = 'newText';
// get back the current HTML content in the
// temporary div element
console.log(temp.innerHTML)
Why not regex?
RegEx match open tags except XHTML self-contained tags
Using regular expressions to parse HTML: why not?
Regex will never be a good decision to parse html content.
Consider the following short solution using DOMParser object(for browsers which support DOMParser implementation, see compatibility table):
var s = "<div style='xxx' class='xxx'>replaceThisText<div>",
tag = (new DOMParser()).parseFromString(s, 'text/html').querySelector('.xxx');
tag.textContent = 'newText'; // replacing with a new text
console.log(tag.outerHTML); // outputs the initial tag representation with replaced content
https://developer.mozilla.org/ru/docs/Web/API/DOMParser

String Filtering.Need to remove the <style> tag and its contents and keep only the contents in <body>

In our project, we are getting a response from the DB. We are using the same string in two ways.
We have to display the text part alone in one line
We are putting the entire content as an HTML.
We are getting a response similar to this.
"<html><head><title>SomeTitle</title></head><style>a.hover{color:green}cc.a{color:red},pq.a{text-decoration:underline}</style> <body> Some content </body></html>"
I need to get the content only from the body using string manipulation.I need to filter out all the contents of the other tags as well.
For example
Final result should be
Some content
I used text() in some case but at times the content inside is also getting displayed. That is not allowed for me.
Note: There are times where I don't get so there should be a check for that as well.
any solution on this?
At times we are getting inside body as well. So is there any way to remove that part off?
for example
var str = "<html><head><title>SomeTitle</title></head><style>a.hover{color:green}cc.a{color:red},pq.a{text-decoration:underline}</style> <body> <style>.hello12{color:green}</style>Some content </body></html>";
and i should get just "some content"
Use DOMParser and get text content from body tag. Where querySelector can be used to get body element and get text content from textContent property.
var str = "<html><head><title>SomeTitle</title></head><style>a.hover{color:green}cc.a{color:red},pq.a{text-decoration:underline}</style> <body> Some content </body></html>";
var parser = new DOMParser();
var doc = parser.parseFromString(str, "text/html");
console.log(
doc.querySelector('body').textContent
)
FYI : To avoid script and style tag content use innerText property instead of textContent property.

Converting string to HTML in JavaScript

I am extracting content from an HTML textarea using JS, in order to then put it into a <div>. Now, I know the content is going to be valid HTML - so I assumed that if I set it as the innerHTML of another element it would be parsed by the browser - but it's not. I'm getting the plain string (with tags and all) on the screen.
This is basically my script:
var txt = document.getElementById("contentTextArea").innerHTML; //Get the content
document.getElementById("contentOutput").innerHTML = txt;
Here's the HTML, just to be sure:
<textarea name="content" id="contentTextArea">
<p>Text...</p>
</textarea>
What am I doing wrong? Is there another way of doing this?
Thanks!
var txt = document.getElementById("contentTextArea").value; //Get the content
Textareas support value not innerHTML. YOu should do this...
document.getElementById("contentTextArea").value;

Display an entire html documention into a frame

I have an entire html document contained in a javascript string variable and I need to render it into a portion of my page. Have I to use frames?
How to do that?
With an iframe:
<iframe id="myiframe"></iframe>
var frame= document.getElementById('myiframe');
var doc= frame.contentDocument? frame.contentDocument : frame.contentWindow.document; // IE compatibility
doc.open('text/html');
doc.write(documenthtml);
doc.close();
Or, if you can cut off the bits you don't want (like any DOCTYPE and <head> element), you can just write innerHTML to any element. Normally handling [X][HT]ML with regexp or string processing is a really bad idea, but if you know that the body will always be contained within the exact strings ‘<body>...</body>’ and there will never be eg. any ‘<body>’ sequence hidden in a comment or script section, you might be able to get away with it.
To be honest, browsers at the moment are so forgiving they will typically even let you write a whole HTML document to a div's innerHTML, complete with doctype and ‘<head>’ in there! But that would be a bit naughty:
<div id="mycontent"></div>
document.getElementById('mycontent').innerHTML= htmldocument;
Here's a nasty hack combining both methods, to extract the body content without the use of regex:
<div id="mycontent"></div>
var frame= document.createElement('iframe');
frame.style.display= 'none';
document.body.appendChild(frame);
var doc= frame.contentDocument? frame.contentDocument : frame.contentWindow.document;
doc.open('text/html');
doc.write(documenthtml);
doc.close();
document.getElementById('mycontent').innerHTML= doc.body.innerHTML;
document.body.removeChild(frame);
document.getElementById('container').innerHTML = string;
This will load the contents of the string inside of an element (probably a div) with the id of "container".
myHtmlString = 'some stuff'; // whatever your big html string is
el = document.getElementById("myTarget"); // where you'd like the html to end up
el.innerHTML = myHtmlString; // set the HTML of el to be your big string.

Categories