2016-01-15 7 views
5

Ich erhalte einige Textdaten mit JSON, diese Daten enthalten Text formatiert mit Zeilenumbrüchen. Ich möchte diese Zeilenumbrüche gerne dem Benutzer rendern.Rendern von Zeilenumbrüchen wie <br> Tags mit Aurelia

Frage: Was ist der "richtig"/"empfehlenswert" Ansatz, um dies zu erreichen?

Optionen Ich habe versucht:

  • Bindung normalerweise: <p>${myText}</p>: Renders keine Zeilenumbrüche
  • <pre> Verwendung: <p><pre>${myText}></pre></p>: Renders Zeilenumbrüche, haben aber alle bekannt und beliebt Probleme mit langen <pre> Text, wie horizontalen Scrollen in einigen Browsern und suboptimales Word breaking.
  • Bindung normalerweise einen Valueconverter verwenden, die Zeilenumbrüche mit <br> Tags ersetzt: <p>${myText | textFormat}</p>
export class TextFormatValueConverter { 
    toView(value) { 
    return value.replace(new RegExp('\r?\n','g'), '<br>'); 
    } 
} 

Diese <br>-Tags nicht machen, aber die Aurelia Binder entweicht die Tags und zeigt sie als normaler Text an den Benutzer. * Bindung mit dem oben genannten Konverter und innerHTML: <p innerHTML.bind="myText | textFormat"></p>: Rendert ok, aber ich bin besorgt, dass es anfällig für Exploits sein könnte, da die Texte von einem Legacy-System kommt, die keine sanitazion Eingang in Bezug auf die Verwendung für das Web tut.

+0

Was [sterilisieren-html] (https://github.com/aurelia/templating-resources/blob/master/src/ sanitize-html.js) Konverter? – dfsq

+0

Danke :) Davon wusste ich nichts. so eine mögliche Lösung wäre, durch das Desinfektionsmittel zu leiten, oder einfach meinen eigenen Konverter zu erweitern, um Hygiene einzubeziehen. Ich glaube, dass einige sanitation in der innerHtml-Bindung enthalten ist (mit Blick auf den Code von Ihnen oben verlinkt, scheint es nur Skripte zu sein, die hier gestoppt werden und ich glaube, dass die innere html davon standardmäßig schützt (könnte aber falsch sein). Ich weiß noch nicht genug, um zu sagen, ob der Schutz vor Skript-Tags gut genug ist oder ob mehr Schutz in Betracht gezogen werden sollte. – Vidar

+0

Siehe ["Sollten Fragen" Tags "in ihren Titeln enthalten?"] (http: //meta.stackexchange. com/questions/19190/should-questions-include-tags-in-the-titles), wo der Konsens "nein, sollten sie nicht!" –

Antwort

4

Was Sie tun, ist richtig. Manchmal ist eine Bindung an innerHTML erforderlich. Die Dokumentation unter aurelia.io enthält Anweisungen zur Verwendung eines Sanierungskonverters und einen Hinweis zur Verwendung einer vollständigeren Implementierung unter Verwendung des sanitize-html-Projekts.

Das heißt, können Sie eine wirklich leichte benutzerdefinierte Attribute erstellen, die nur das tut, was Sie brauchen:

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> 
+0

kann es auch als ein benutzerdefiniertes Element gemacht werden? ' $ {myText}' Oder bringt das viel Overhead? – Vidar

+0

Nachdenken darüber, ein Attribut macht sehr viel Sinn, da es auf verschiedene Elemente wiederverwendet werden kann. – Vidar

+0

Richtig - ein Attribut ist flexibler für so etwas, aber ein benutzerdefiniertes Element würde auch funktionieren. –

2

Das Problem ist, dass Aurelia konvertiert HTML als Escape-Tags. Um dies zu umgehen verwenden Sie einfach Ihre RegExp Funktion <br> zu konvertieren, verwenden Sie dann innerHTML- wie so verbindlich:

<p innerHTML.bind=“htmlText”>${myText}</p> 

Dies wird Aurelia-Station von der HTML entkommen. Ich sehe, dass Sie sich Sorgen machen, diesen Ansatz zu verwenden, da Sie befürchten, dass irgendwo schlechtes HTML sein könnte, aber es gibt keine andere Möglichkeit, dies zu umgehen, da Sie Aurelia nicht sagen können, dass nur bestimmte Tags gerendert werden.

Wenn Sie sind, die über das Potenzial für schlechte HTML betroffen sind, warum schreiben Sie nicht ein Stück von benutzerdefinierten JS zu unescape alle <br> Tags nach dem Laden der Seite? (Hässlich, aber ich kann keinen anderen Weg sehen.)

+0

könnte es möglich sein, eine Funktion zu verwenden, die alle Tags durch sichere Tags ersetzt und BRs zurück in unsichere konvertiert und dann an innerHTML bindet. Das würde es grundsätzlich lösen, oder? (Ich habe keine Aurelia Erfahrung) – DoXicK

+0

Warum der Downvote? Die angenommene Antwort macht genau das, was ich vorschlage, aber ich behalte die Wagenrückgabe, anstatt mit Unescaped zu arbeiten. –

+0

keine Ahnung, war nicht ich ... denke, das Plakat wurde gehässig: -/ – DoXicK

Verwandte Themen