2015-08-05 7 views
15

L'utente immette messaggi di chat, che vengono visualizzati direttamente sulla pagina utilizzando i modelli di baffi. Ovviamente, l'HTML dovrebbe essere sottoposto a escape per impedire l'inserimento di HTML, ma i collegamenti dovrebbero essere resi come <a href='...'>.Escape dai messaggi di chat generati dall'utente ma il rendering dei collegamenti

Esistono diversi approcci che ho provato a utilizzare {{{ ... }}} per restituire il contenuto HTML senza escape, il che significa che il collegamento verrà visualizzato e che mi devo occupare dell'esclusione dell'HTML da solo. C'è un modo sicuro per farlo senza fare affidamento su una soluzione semi-cotta che scrivo da solo?

jQuery.text() sarebbe ottimo, ma suppongo che renderà il <a> nuovamente come testo.

Cos'altro posso fare qui?

+1

Cosa pensi di usare diversi tipi di markup per i collegamenti in videochat, come BBCode o Markdown? Questo è il modo in cui di solito funziona su vari forum di discussione e qui. – JacobMiki

+1

@JacobMiki Ma non si tratta di stabilire una sintassi generale per il markdown, ma solo per il rendering dei collegamenti. Anche Facebook Chat non ha bisogno di questo. – Mahoni

risposta

10

Se non si desidera scrivere la propria soluzione di escaping o parsing, esiste un plug-in jQuery per gestire i collegamenti chiamati Linkify. Potresti semplicemente sfuggire ai messaggi e quindi analizzarli sul lato client.

Esempio di come funziona:

var text = "<div>Test<br>Test<br>Test http://stackoverflow.com</div>"; 
$('div').text(text); 

// Before: &lt;div&gt;Test&lt;br&gt;Test&lt;br&gt;Test http://stackoverflow.com&lt;/div&gt; 

$('div').linkify(); 

// After: lt;div&gt;Test&lt;br&gt;Test&lt;br&gt;Test <a href="http://stackoverflow.com" class="linkified" target="_blank">http://stackoverflow.com</a>&lt;/div&gt; 
0

Solo un'idea: Si potrebbe costruire una propria funzione escape

escape : function() { 
    return function(val, render) { 
     var $s = $(val); 
     var $elements = $s.find("*").not("a"); //add other white-listed elements seperated by comma 
     for (var i = $elements.length - 1; i >= 0; i--) { 
      var e = $elements[i]; 
      $(e).replaceWith(e.innerHTML); 
     } 
     return $s.html(); 
    } 
} 

È possibile chiamare la funzione

{{#escape}}{{{YOUR_TEXT}}}{{/escape}} 

non ho ancora testato questo. Questa soluzione ha bisogno di jQuery. Il codice sopra riportato si basa su questa soluzione: https://stackoverflow.com/a/27764431/1479486

0

provare inserendo prima .text() e quindi utilizzare regexp per rendere il legame con html(). Qui potete vedere un esempio di vaniglia:

var a="see formula a<b>c in http://test.com or https://x.com?p=3"; 

var hold=document.createElement('div'); 
hold.textContent=a; 

hold.innerHTML=hold.innerHTML.replace(
    /(https?:\/\/[-$A-Za-z0-9%_?&.~+\/=]+)/g, 
    '<a href="$1">$1</a>' 
); 

window.addEventListener('load',function(){ 
    document.body.appendChild(hold); 
}); 

Per un'espressione regolare più una precisione è possibile vedere here

+1

[Qui] (https://mathiasbynens.be/demo/url-regex) puoi vedere più alternative per l'espressione regolare –

0

Se si finisce per andare verso il basso il percorso regex il seguente filtro ed espressioni regolari è stato il più aggressivo che ho trovato per raccogliendo tutti i tipi di URL che i tuoi utenti cercheranno di digitare.

Heres un RegExr per giocare con essa: http://regexr.com/3bjk9

(function() { 
    'use strict'; 

    angular 
     .module('core.filters') 
     .filter('urlToA', urlToA); 

    // -------------------- 

    function urlToA() { 
     return function (string, noClick) { 
      var urlPattern = /((?:(http|https|Http|Https|rtsp|Rtsp):\/\/(?:(?:[a-zA-Z0-9\$\-\_\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,64}(?:\:(?:[a-zA-Z0-9\$\-\_\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,25})?\@)?)?((?:(?:[a-zA-Z0-9][a-zA-Z0-9\-]{0,64}\.)+(?:(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(?:biz|b[abdefghijmnorstvwyz])|(?:cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(?:edu|e[cegrstu])|f[ijkmor]|(?:gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(?:info|int|i[delmnoqrst])|(?:jobs|j[emop])|k[eghimnrwyz]|l[abcikrstuvy]|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])|(?:name|net|n[acefgilopruz])|(?:org|om)|(?:pro|p[aefghklmnrstwy])|qa|r[eouw]|s[abcdeghijklmnortuvyz]|(?:tel|travel|t[cdfghjklmnoprtvwz])|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw]))|(?:(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[0-9])))(?:\:\d{1,5})?)(\/(?:(?:[a-zA-Z0-9\;\/\?\:\@\&\=\#\~\-\.\+\!\*\'\(\)\,\_])|(?:\%[a-fA-F0-9]{2}))*)?(?:\b|$)/gi; // jshint ignore:line 

      return string ? string.replace(urlPattern, replace) : string; 

      function replace (url) { 
       var httpUrl = url.indexOf('http') === -1 ? 'http://' + url : url; 

       if (noClick) { 
        return '<a>' + url + '</a>'; 
       } else { 
        return '<a href="' + httpUrl + '">' + url + '</a>'; 
       } 
      } 
     }; 
    } 

})(); 
Problemi correlati