AngularJS中$sce.trustAsHtml处理含<script>标签内容及脚本执行问题
嘿,这个问题我之前做AngularJS项目时刚好踩过坑!AngularJS的ng-bind-html出于安全考量,默认会过滤掉<script>标签,而且就算你绕开了过滤,浏览器也不会自动执行动态插入的script;另外带ng-controller的HTML片段,Angular也不会主动去编译它,得手动处理。下面分两部分给你解决:
一、让动态加载的
<script>执行弹出提示框 首先,Angular的$sanitize服务会自动移除HTML里的<script>标签,所以第一步得用$sce.trustAsHtml()来标记这段HTML是可信的,不过这还不够——就算HTML被插入到DOM里,浏览器也不会主动执行动态添加的script内容,得手动提取并执行。
这里给你完整的实现示例:
控制器代码
app.controller('MyCtrl', function($scope, $http, $sce, $timeout) { $http.get('/your-api-endpoint').then(function(response) { // 1. 标记HTML为可信,避免被$sanitize过滤 $scope.htmlContent = $sce.trustAsHtml(response.data); // 2. 等待Angular完成DOM渲染后,处理script标签 $timeout(function() { // 获取承载HTML的容器 var container = document.getElementById('html-container'); // 提取容器内所有script标签 var scripts = container.getElementsByTagName('script'); // 遍历每个script,执行其内容 angular.forEach(scripts, function(script) { // 创建新的script元素 var newScript = document.createElement('script'); // 把原script的内容复制进去 newScript.text = script.innerHTML; // 插入到body中,浏览器会自动执行 document.body.appendChild(newScript); // 可选:移除原DOM中的script标签,避免重复处理 script.remove(); }); }); }); });
页面HTML
<div id="html-container" ng-bind-html="htmlContent"></div>
注意:用$timeout是为了确保Angular已经完成了HTML的渲染,这时候才能准确获取到插入的script标签。另外,这种方式一定要确保加载的HTML来源是绝对可信的,否则会有XSS攻击的风险!
二、处理包含
ng-controller的动态HTML 如果动态HTML里有ng-controller这类Angular指令,ng-bind-html只会把标签插入DOM,但Angular不会自动编译这段内容,控制器自然不会生效。这时候得用$compile服务来手动编译并链接到作用域。
示例代码如下:
控制器代码
app.controller('MyCtrl', function($scope, $http, $compile) { $http.get('/your-api-endpoint').then(function(response) { var rawHtml = response.data; var container = angular.element(document.getElementById('html-container')); // 1. 编译HTML:把Angular指令转换成可执行的DOM元素 // 2. 链接到当前作用域(也可以用$scope.$new()创建子作用域隔离) var compiledElement = $compile(rawHtml)($scope); // 清空容器,插入编译后的元素 container.empty().append(compiledElement); // 如果用子作用域,记得在不需要的时候销毁,避免内存泄漏 // var childScope = $scope.$new(); // var compiledElement = $compile(rawHtml)(childScope); // ... // childScope.$destroy(); }); });
页面HTML
<div id="html-container"></div>
这样处理后,动态HTML里的ng-controller会被Angular正常识别,控制器也会初始化并生效。同样要注意,必须确保加载的HTML来源可信,防止注入恶意代码。
内容的提问来源于stack exchange,提问作者d-_-b
相关产品推荐
相关产品推荐

