admin管理员组文章数量:1327713
I am retrieving some textual data using JSON, this data includes text formatted with linebreaks. I would very much like to render those linebreaks to the user.
Question: What is the "correct" / "remended" approach to achieve this?
Options I've tried:
- Binding normally:
<p>${myText}</p>
: Renders no linebreaks - Using
<pre>
:<p><pre>${myText}></pre></p>
: Renders linebreaks, but have all the known and loved issues with long<pre>
text, like horizontal scrolling in some browsers and suboptimal word breaking. - Binding normally using a valueConverter that replaces linebreaks with
<br>
tags:<p>${myText | textFormat}</p>
export class TextFormatValueConverter {
toView(value) {
return value.replace(new RegExp('\r?\n','g'), '<br>');
}
}
This does render <br>
tags, but the Aurelia binder escapes the tags and shows them as literal text to the user.
* Binding using the above converter and innerHTML: <p innerHTML.bind="myText | textFormat"></p>
: Renders ok but I'm worried that it might be vulnerable to exploits, as the texts es from a legacy system that does not do any input sanitazion with regards to usage for the web.
I am retrieving some textual data using JSON, this data includes text formatted with linebreaks. I would very much like to render those linebreaks to the user.
Question: What is the "correct" / "remended" approach to achieve this?
Options I've tried:
- Binding normally:
<p>${myText}</p>
: Renders no linebreaks - Using
<pre>
:<p><pre>${myText}></pre></p>
: Renders linebreaks, but have all the known and loved issues with long<pre>
text, like horizontal scrolling in some browsers and suboptimal word breaking. - Binding normally using a valueConverter that replaces linebreaks with
<br>
tags:<p>${myText | textFormat}</p>
export class TextFormatValueConverter {
toView(value) {
return value.replace(new RegExp('\r?\n','g'), '<br>');
}
}
This does render <br>
tags, but the Aurelia binder escapes the tags and shows them as literal text to the user.
* Binding using the above converter and innerHTML: <p innerHTML.bind="myText | textFormat"></p>
: Renders ok but I'm worried that it might be vulnerable to exploits, as the texts es from a legacy system that does not do any input sanitazion with regards to usage for the web.
- What about sanitize-html converter? – dfsq Commented Jan 15, 2016 at 10:39
- Thanks :) Did not know about that one. so one possible solution would be to pipe through the sanitizer, or just extend my own converter to include sanitation. I do believe some sanitation is included in the innerHtml binding (looking at the code of you linked above, it seems to be just scripts that are stopped here and I belive the innerHtml protects from that by default (could be wrong though). I'm not yet knowledgeable enough to say if protecting from script tags is good enough or if more protection should be considered.. – Vidar Commented Jan 15, 2016 at 11:10
- Please see "Should questions include “tags” in their titles?", where the consensus is "no, they should not"! – user57508 Commented Jan 15, 2016 at 11:28
- 1 @AndreasNiedermair sometimes they should when they make the question clearer. This is one of those cases. – Jeremy Danyow Commented Jan 15, 2016 at 13:54
- @JeremyDanyow this is not one of the cases, where tags should be used, but rather a plete sentence for the title should be the target ... Tags are never the way to go! – user57508 Commented Jan 15, 2016 at 14:35
3 Answers
Reset to default 4What you're doing is correct. Binding to innerHTML
is sometimes necessary. The docs at aurelia.io include instructions for using a sanitization converter and a note about using a more plete implementation using the sanitize-html project.
That said, you can create a really light-weight custom attribute that does only what you need:
http://plnkr.co/edit/qykvo9PKAD0TawTlQ5sp?p=preview
preserve-breaks.js
import {inject} from 'aurelia-framework';
function htmlEncode(html) {
return document.createElement('a').appendChild(
document.createTextNode(html)).parentNode.innerHTML;
}
@inject(Element)
export class PreserveBreaksCustomAttribute {
constructor(element) {
this.element = element;
}
valueChanged() {
let html = htmlEncode(this.value);
html = html.replace(/\r/g, '').replace(/\n/g, '<br/>');
this.element.innerHTML = html;
}
}
app.js
export class App {
message = `this is my text
it has some line breaks
and some <script>evil javascript</script>
the line breaks were replaced with <br/> tags`;
}
app.html
<template>
<require from="./preserve-breaks"></require>
<div preserve-breaks.bind="message"></div>
</template>
The problem is that Aurelia renders your converted HTML as escaped tags. To get around this just use your RegExp function to convert to <br>
, then use innerHTML binding like so:
<p innerHTML.bind=“htmlText”>${myText}</p>
This will stop Aurelia from escaping the HTML. I see you're worried about using this approach, as you're afraid there could be bad HTML somewhere, but there's no other way to get around this as you can't tell Aurelia to only render specific tags.
If you're that concerned about the potential for bad HTML, why don't you write a piece of custom JS to unescape all the <br>
tags after page load? (Ugly as hell, but I can't see another way.)
I have found solution on Github :
usage of style="white-space: pre-wrap;"
on parent element fixes issue.
本文标签: javascriptHow to render linebreaks as ltbrgt tags with AureliaStack Overflow
版权声明:本文标题:javascript - How to render linebreaks as <br> tags with Aurelia - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742230806a2437187.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论