Javascript AngularJS过滤器以字符串形式返回html

Javascript AngularJS过滤器以字符串形式返回html,javascript,angularjs,angularjs-filter,Javascript,Angularjs,Angularjs Filter,我创建了一个AngularJS过滤器,可以根据数据中的地址自动创建可点击的链接。过滤器: app.filter('parseUrl', function() { var //URLs starting with http://, https://, or ftp:// replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim,

我创建了一个AngularJS过滤器,可以根据数据中的地址自动创建可点击的链接。过滤器:

app.filter('parseUrl', function() {
    var  //URLs starting with http://, https://, or ftp://
        replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim,
        //URLs starting with "www." (without // before it, or it'd re-link the ones done above).
        replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim,
        //Change email addresses to mailto:: links.
        replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim;

        return function(text, target, otherProp) {        
            angular.forEach(text.match(replacePattern1), function(url) {
                text = text.replace(replacePattern1, "<a href=\"$1\" target=\"_blank\">$1</a>");
            });
            angular.forEach(text.match(replacePattern2), function(url) {
                text = text.replace(replacePattern2, "$1<a href=\"http://$2\" target=\"_blank\">$2</a>");
            });
            angular.forEach(text.match(replacePattern3), function(url) {
                text = text.replace(replacePattern3, "<a href=\"mailto:$1\">$1</a>");
            });

            return text;        
        };
    });
app.filter('parseUrl',function(){
var//以http://、https://或ftp开头的URL://
replacePattern1=/(\b(https?| ftp):\/\/[-A-Z0-9+&@#\/%?=~~|!:,.;]*[-A-Z0-9+&@#\/%=~|]/gim,
//以“www.”开头的URL(前面没有//或它会重新链接上面的内容)。
replacePattern2=/(^.[^\/])(www\.[\S]+(\b\$)/gim,
//将电子邮件地址更改为mailto::links。
replacePattern3=/(\w+@[a-zA-Z\+?\[a-zA-Z]{2,6})/gim;
返回函数(文本、目标、其他属性){
angular.forEach(text.match(replacePattern1),函数(url){
text=text.replace(replacePattern1,“”);
});
angular.forEach(text.match(replacePattern2),函数(url){
text=text.replace(replacePattern2,“$1”);
});
angular.forEach(text.match(replacePattern3),函数(url){
text=text.replace(replacePattern3,“”);
});
返回文本;
};
});
下面是我如何称呼它(在一段中):

详细信息:{{event.description | parseUrl}

这可以正确地用链接代码替换纯文本链接。但是,它将其替换为纯文本形式的链接。例如,
www.google.com
将替换为
a href=”http://www.google.com“target=“\u blank”http://google.com/a
。这显然不是一个可点击的链接,这是我的目标

我不知道为什么会这样。关于如何预防/修复它有什么想法吗?谢谢。

尝试使用指令将过滤器生成的HTML应用为元素的实际innerHTML内容,如下所示:

<span ng-bind-html-unsafe="event.description | parseUrl"></span>

您需要使用以下任一选项:


  • 如果您100%信任内容的来源

  • 如果您不信任内容的来源

使用表达式输出字符串将转义传递给它的任何html实体(符号,如<>&)

我使用这个过滤器有一段时间了,不知何故没有注意到它产生的灾难性后果。我的修改版本如下:

filter('parseUrl', function($sce) {
var  //URLs starting with http://, https://, or ftp://
    replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim,
    //URLs starting with "www." (without // before it, or it'd re-link the ones done above).
    replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim,
    //Change email addresses to mailto:: links.
    replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim;

    return function(text, target, otherProp) {        
        text = (text + '').replace(/>/,"&gt;").replace(/</,"&lt;");
        text = (text + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br>$2');
        text = text.replace(replacePattern1, "<a href=\"$1\" target=\"_blank\">$1</a>");
        text = text.replace(replacePattern2, "<a href=\"http://$2\" target=\"_blank\">$2</a>");
        text = text.replace(replacePattern3, "<a href=\"mailto:$1\">$1</a>");
        return $sce.trustAsHtml(text);
    };
});
filter('parseUrl',函数($sce){
var//以http://、https://或ftp开头的URL://
replacePattern1=/(\b(https?| ftp):\/\/[-A-Z0-9+&@#\/%?=~~|!:,.;]*[-A-Z0-9+&@#\/%=~|]/gim,
//以“www.”开头的URL(前面没有//或它会重新链接上面的内容)。
replacePattern2=/(^.[^\/])(www\.[\S]+(\b\$)/gim,
//将电子邮件地址更改为mailto::links。
replacePattern3=/(\w+@[a-zA-Z\+?\[a-zA-Z]{2,6})/gim;
返回函数(文本、目标、其他属性){
text=(text+“”).replace(/>/,“”)。replace(/\r\n]?)(\r\n |\n\r |\r |\n)/g,“$1
$2”); text=text.replace(replacePattern1,“”); text=text.replace(replacePattern2,“”); text=text.replace(replacePattern3,“”); 返回$sce.trustAsHtml(文本); }; });

注意,它没有使用angular.forEach!(???????)当它这样做的时候,输出会变得异常激烈。大概这个问题与有多个匹配有关

您可能想看看ngSanitize模块中AngularJS提供的“linky”过滤器()——该过滤器可能已经完成了您需要的功能,它的文档支持答案中关于ng bind html/ng bind html不安全指令的建议。不幸的是,新版本的AngularJS中没有此类指令。使用
ng bind html不安全
不是一个好主意,因为它会带来潜在的安全风险。我认为这是它被弃用的原因之一。与我的主要问题中的原因不同,我实际上使用了一个叉子:
filter('parseUrl', function($sce) {
var  //URLs starting with http://, https://, or ftp://
    replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim,
    //URLs starting with "www." (without // before it, or it'd re-link the ones done above).
    replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim,
    //Change email addresses to mailto:: links.
    replacePattern3 = /(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim;

    return function(text, target, otherProp) {        
        text = (text + '').replace(/>/,"&gt;").replace(/</,"&lt;");
        text = (text + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br>$2');
        text = text.replace(replacePattern1, "<a href=\"$1\" target=\"_blank\">$1</a>");
        text = text.replace(replacePattern2, "<a href=\"http://$2\" target=\"_blank\">$2</a>");
        text = text.replace(replacePattern3, "<a href=\"mailto:$1\">$1</a>");
        return $sce.trustAsHtml(text);
    };
});