最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to render linebreaks as <br> tags with Aurelia - Stack Overflow

programmeradmin5浏览0评论

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.

Share Improve this question edited Jan 15, 2016 at 13:55 Jeremy Danyow 26.4k12 gold badges90 silver badges135 bronze badges asked Jan 15, 2016 at 10:17 VidarVidar 2922 silver badges12 bronze badges 5
  • 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
Add a ment  | 

3 Answers 3

Reset to default 4

What 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.

发布评论

评论列表(0)

  1. 暂无评论