ianbeks ianbeks - 2 months ago 17
Ajax Question

ReactJS - How to render carriage returns correctly when returned in Ajax call

In ReactJS, how is it possible to render carriage returns that may be submitted by the user in a

textarea control
. The content containing the carriage returns is retrieved by an Ajax call which calls an API that needs to convert the
\r\n
characters to
<br>
or something else. And then, I have a
div
element in which the content should be rendered. I tried the following Ajax responses:

{
"Comment" : "Some stuff followed by line breaks<br/><br/><br/><br/>And more stuff.",
}


and

{
"Comment" : "Some stuff followed by line breaks\n\n\nAnd more stuff.",
}


But instead of rendering the carriage returns in the browser, it renders the br tags as plain text in the first case and \n character as space in the second case.

What's the recommended approach here? I'm guessing I should steer clear of the scary
dangerouslySetInnerHTML
property? For example the following would actually work but there must a safer way of handling carriage returns:

<div className="comment-text" dangerouslySetInnerHTML={{__html: comment.Comment}}></div>

Answer

dangerouslySetInnerHTML is what you want. The name is meant to be scary, because using it presents a risk for XSS attacks, but essentially it's just a reminder that you need to sanitize user inputs (which you should do anyway!)

To see an XSS attack in action while using dangerouslySetInnerHTML, try having a user save a comment whose text is:

Just an innocent comment.... <script>alert("XSS!!!")</script>

You might be surprised to see that this comment will actually create the alert popup. An even more malicious user might insert JS to download a virus when anyone views their comment. We obviously can't allow that.

But protecting against XSS is pretty simple. Sanitization needs to be done server side, but there are plenty of packages available that do this exact task for any conceivable serverside setup.

Here's an example of a good package for Rails, for example: https://github.com/rgrove/sanitize

Just be sure whichever sanitizer you pick uses a "whitelist" sanitization method, not a "blacklist" one.