javascript - 为什么这个过滤器不输出 IFRAME?

标签 javascript angularjs angularjs-filter

我正在尝试自动嵌入 YouTube 视频以显示用户生成的内容。我的过滤器通常会查找链接,然后测试它们以查看它们是否是有效的 YouTube 视频。如果是,则应使用标准 iframe 代码嵌入视频。如果没有,那只是一个链接。但是,过滤器根本不输出 iframe 代码。我假设这可以防止跨站点脚本攻击,但我不知道如何绕过它。

function ytVidId(url) {
  var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
  return (url.match(p)) ? RegExp.$1 : false;
}

myapp.filter('parseUrls', function() {
    //with protocol
    var urlPattern = /(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?/gi;
    return function(text, target, otherProp) {        
        if (text == null) {
            return "";
        }
        angular.forEach(text.match(urlPattern), function(url) {
            if(ytVidId(url)){
                text = text.replace(url, '<div class="video-container"><iframe src="//www.youtube.com/embed/'+ ytVidId(url) +'" frameborder="0" width="560" height="315"></iframe></div>');
            }else{
                text = text.replace(url, '<a target="' + target + '" href='+ url + '>' + url + '</a>');
            }

        });
        return text;        
    };
})

使用中:

<span ng-bind-html="p.body | noHTML | newlines | parseUrls:'_blank'"></span>

最佳答案

Angular 要求您通过“sce”(严格上下文转义)提供程序传递 HTML。

Documentation on the SCE provider here

所以它看起来像这样(未经测试,但理论上应该如此)

function ytVidId(url) {
  var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
  return (url.match(p)) ? RegExp.$1 : false;
}    

myapp.filter('parseUrls', ['$sce', function() {
    //with protocol
    var urlPattern = /(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&amp;:\/~+#-]*[\w@?^=%&amp;\/~+#-])?/gi;
    return function(text, target, otherProp) {        
        if (text == null) {
            return "";
        }
        angular.forEach(text.match(urlPattern), function(url) {
            if(ytVidId(url)){
                text = text.replace(url, $sce.trustAs('html', '<div class="video-container"><iframe src="//www.youtube.com/embed/'+ ytVidId(url) +'" frameborder="0" width="560" height="315"></iframe></div>'));
            }else{
                text = text.replace(url, $sce.trustAs('html', '<a target="' + target + '" href='+ url + '>' + url + '</a>'));
            }    

        });
        return text;        
    };
}])`

关于javascript - 为什么这个过滤器不输出 IFRAME?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24443373/

相关文章:

javascript - 使用 AngularJS Filter 过滤数据。如何迭代对象?

php - 针对不同页面上的 iFrame 的表单

javascript - 制作一键启动功能,一键停止功能

angularjs - 如何在页面加载时执行 AngularJS Controller 功能?

angularjs - 尝试调用 'error TS2349: Cannot invoke an expression whose type lacks a call signature' 中的自定义过滤器结果

javascript - array1.filter 不是函数 ng-tags-input

javascript - YouTube JS API : play by random time point on button click

javascript - 设置cookie并重定向,不带express

angularjs - 无法读取AngularJS中未定义的属性 'replace'?

javascript - 使用 ngStorage 将数据绑定(bind)到 localStorage - 这里出了什么问题?