2016-01-15 10 views
5

Sto recuperando alcuni dati testuali utilizzando JSON, questi dati includono testo formattato con interruzioni di riga. Mi piacerebbe molto rendere questi linebreak all'utente.Come rendere i linebreak come tag <br> con Aurelia

Domanda: Qual è il "corretto"/"consigliato" approccio per raggiungere questo obiettivo?

opzioni che ho provato:

  • Rilegatura normalmente: <p>${myText}</p>: non svolge linebreaks
  • Utilizzando <pre>: <p><pre>${myText}></pre></p>: Renders linebreaks, ma hanno tutti i problemi noti e amati con lunghi <pre> testo, come orizzontale scorrendo alcuni browser e rompendo in modo subottimale.
  • Binding normalmente utilizzando un ValueConverter che sostituisce linebreaks con <br> tags: <p>${myText | textFormat}</p>
export class TextFormatValueConverter { 
    toView(value) { 
    return value.replace(new RegExp('\r?\n','g'), '<br>'); 
    } 
} 

Ciò rende <br> tag, ma il legante Aurelia sfugge i tag e mostra loro testo letterale all'utente. * Binding utilizzando il convertitore sopra e innerHTML: <p innerHTML.bind="myText | textFormat"></p>: Rende bene, ma sono preoccupato che potrebbe essere vulnerabile agli exploit, in quanto i testi provengono da un sistema legacy che non esegue alcun sanitation di input per quanto riguarda l'utilizzo per il web.

+0

Che dire [disinfettare-html] (https://github.com/aurelia/templating-resources/blob/master/src/ sanitize-html.js) convertitore? – dfsq

+0

Grazie :) Non lo sapevo. così una possibile soluzione sarebbe quella di passare attraverso il disinfettante, o semplicemente estendere il mio convertitore per includere servizi igienico-sanitari. Credo che alcuni servizi igienico-sanitari siano inclusi nel binding innerHtml (guardando il codice di te linkato sopra, sembra che siano solo degli script che vengono fermati qui e credo che il innerHtml protegga da quello di default (potrebbe essere sbagliato però). Non ancora sufficientemente informato da dire se proteggere dai tag script è sufficiente o se occorre prendere in considerazione una maggiore protezione .. – Vidar

+0

Si prega di consultare ["Le domande dovrebbero includere" tag "nei loro titoli?"] (http: //meta.stackexchange. it/questions/19190/should-questions-include-tags-in-their-titles), dove il consenso è "no, non dovrebbero"! –

risposta

4

Quello che stai facendo è corretto. Il collegamento a innerHTML è talvolta necessario. I documenti su aurelia.io includono istruzioni per l'uso di un convertitore di disinfezione e una nota sull'utilizzo di un'implementazione più completa utilizzando il progetto sanitize-html.

Detto questo, è possibile creare un attributo molto leggero personalizzato che fa solo quello che ti serve:

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

può anche essere fatto come un elemento personalizzato? ' $ {myText}' Oppure questo porterà un sacco di spese generali? – Vidar

+0

Pensando a questo, un attributo ha molto senso, in quanto può essere riutilizzato su diversi elementi. – Vidar

+0

right- un attributo è più flessibile per qualcosa di simile, ma un elemento personalizzato funzionerebbe pure. –

2

Il problema è che Aurelia esegue il rendering del codice HTML convertito come tag di escape. Per ovviare a questo basta usare la funzione RegExp per convertire in <br>, quindi utilizzare innerHTML vincolante in questo modo:

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

Questo fermerà Aurelia da sfuggire al HTML. Vedo che sei preoccupato dell'utilizzo di questo approccio, poiché temo che possa esserci un codice HTML errato da qualche parte, ma non c'è altro modo per aggirare questo problema perché non puoi dire ad Aurelia di visualizzare solo tag specifici.

Se sei che preoccupato per il potenziale per il cattivo HTML, perché non si scrive un pezzo di costume JS per unescape tutte le <br> tag dopo caricamento della pagina? (Brutto da morire, ma non riesco a vedere un altro modo.)

+0

potrebbe essere possibile utilizzare una funzione che sostituisce tutti i tag con i tag sicuri e converte BR in modo non sicuro, quindi collegalo a innerHTML. Questo fondamentalmente lo risolverebbe, giusto? (Non ho esperienza di aurelia) – DoXicK

+0

Perché il downvote? La risposta accettata fa esattamente ciò che suggerisco, ma mantenendo il ritorno a capo invece di lavorare senza caratteri di escape. –

+0

no indizio, non ero io ... Immagino che il poster sia stato dispettoso: -/ – DoXicK

Problemi correlati