Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DangerouslySetInnerHtml not working properly on simple example. #7825

Closed
sergiotapia opened this issue Sep 28, 2016 · 7 comments
Closed

DangerouslySetInnerHtml not working properly on simple example. #7825

sergiotapia opened this issue Sep 28, 2016 · 7 comments
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@sergiotapia
Copy link

sergiotapia commented Sep 28, 2016

Using React 15.3.0 latest.

Here's what I tried and how it goes wrong.

This works:

<div dangerouslySetInnerHTML={{ __html: "<h1>Hi there!</h1>" }} />

This doesn't:

<div dangerouslySetInnerHTML={{ __html: this.props.match.description }} />

The description property is just a normal string of HTML content. However it's rendered as a string, not as HTML for some reason.

enter image description here

Any suggestions?

@jimfb
Copy link
Contributor

jimfb commented Sep 28, 2016

That would seem unlikely. Either way, React just gets a string in, so React can't actually tell the difference between those two examples. If you can demonstrate in a jsfiddle, we can investigate further.

@jimfb jimfb added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Sep 28, 2016
@sergiotapia
Copy link
Author

I had to unescape the HTML for it to work.

'&lt;h1&gt;Hi there!&lt;/h1&gt;'

Should react automatically unescape html since we're already calling DangerouslySetInnerHtml?

@brigand
Copy link
Contributor

brigand commented Sep 29, 2016

@sergiotapia that escaped html is perfectly valid html. Unescaping it could allow for XSS attacks and incorrect rendering.

@sergiotapia
Copy link
Author

sergiotapia commented Sep 29, 2016

I thought that was the point though, dangerouslySetInnerHtml. Right now I have to create a div set it's html, then extract the html again. Not a good solution.

htmlDecode(content) {
  let e = document.createElement('div');
  e.innerHTML = content;
  return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}

There should be a method that tells React to just do it.

@syranide
Copy link
Contributor

@sergiotapia
'&lt;h1&gt;Hi there!&lt;/h1&gt;' renders to the visible text <h1>Hi there!</h1>.
'<h1>Hi there!</h1>' renders to an H1 with the text Hi there!, which is what you're expecting.

Both are valid HTML, but if it's the second result you expect then you shouldn't be storing it escaped like in the first example, it is wrong. React is working correctly, it's your stored representation that has been unnecessarily/incorrectly escaped.

@aweary aweary closed this as completed Dec 7, 2016
@Slowly
Copy link

Slowly commented Dec 10, 2019

I thought that was the point though, dangerouslySetInnerHtml. Right now I have to create a div set it's html, then extract the html again. Not a good solution.

htmlDecode(content) {
  let e = document.createElement('div');
  e.innerHTML = content;
  return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}

There should be a method that tells React to just do it.

...But they will never allow that, so we have to kludge for very rare instances, such as rendering fetch() response object output as HTML into a Context API Consumer. The ES6 fetch() API Response Object only outputs two forms: JSON, and text. The ONLY solution - yours - will fire a re-render of the Consumer component, rendering the text as valid HTML. This solution IS viable and is secure in any situation where innerHTML() is NOT processing user input - it is processing data read from a file, or data read from a web service.

So, when you get a chance, could you post your complete solution here.

Thank you.

@xgqfrms
Copy link

xgqfrms commented Apr 7, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

8 participants
@Slowly @sergiotapia @brigand @syranide @aweary @xgqfrms @jimfb and others