【问题标题】:How to avoid adding prefix "unsafe" to javascript by AngularJs?如何避免AngularJs向javascript添加前缀“不安全”?
【发布时间】:2015-08-12 15:40:49
【问题描述】:

我尝试将书签按钮添加到我的网站,并在控制器中生成链接。

模板部分:

    <a id="bookmarklet"
       class="bookmarklet"
       onclick="alert('Drag and drop me to the bookmarks bar');return false;"
       href="{{getCode()}}">
      + Add
    </a>

控制器部分:

$scope.getCode = function () {
  var code = 'javascript:(function(){s=document.createElement(\'SCRIPT\');s.type=\'text/javascript\';' +
    's.src=\'http://localhost:9000/scripts/bookmarklet/bookmarklet.js?x=' + ($scope.user.id) + '\';' +
    'document.getElementsByTagName(\'head\')[0].appendChild(s);document.sc_srvurl=\'http://localhost:8080\'})();'  ;
  return code;
};

但编译后我得到以下信息:

<a class="bookmarklet" href="unsafe:javascript:(function(){s=document.createElement('SCRIPT');s.type='text/javascript';s.src='http://localhost:9000/scripts/bookmarklet/bookmarklet.js?x=5517325d40c37bc2bfe20db6';document.getElementsByTagName('head')[0].appendChild(s);document.sc_srvurl='http://localhost:8080'})();">
              + Add
            </a>

链接以“unsafe”开头,我不知道如何告诉 Angular 信任此链接。

这个答案 - Angular changes urls to "unsafe:" in extension page 建议将协议添加到白名单。 我不想禁用 $sce 或将“javascript”添加到白名单协议,因为我认为它不安全。

我可以告诉 angularjs 避免使用 $sce 添加前缀“不安全”吗?不幸的是,我的文档不清楚,$sce.trustAsJs(code) 没有帮助我。

!EDIT Angular 版本是 1.4.1。

【问题讨论】:

  • stackoverflow.com/questions/15606751/… 中的解决方案是将协议添加到白名单,在我的情况下我关心的是安全性。
  • 我认为您没有其他选择。而且您不会添加“javascript”,而是将“chrome-extension”添加到白名单中。
  • 这确实是一个值得关注的问题。我能想到的另一种方法是创建一个指令并在那里设置 href 属性的值(通过直接在指令的 DOM 元素上操作它)。这对您的用例可行吗?
  • @plamut 我不清楚指令的解决方法如何提供帮助。我想知道有没有直接的方法告诉 Angular 信任这个 url?

标签: angularjs


【解决方案1】:

尝试通过编写自定义指令来规避限制:

var app = angular.module('myApp', []);

app.directive('bookmarklet', function () {
    return {
        restrict: 'A',
        scope: {},
        link: function($scope, element, attrs) {
            if (element[0].tagName !== 'A') {
                return;  // simply do nothing (or raise an error)
            }
            element[0].href = 'javascript:alert("It works in 1.4.1, too!")';
        }
    };
 });

用法:

<div ng-app="myApp">
    <a href="#foo" bookmarklet>click me</a>
</div>

我还创建了一个小提琴演示来测试它:http://jsfiddle.net/t0acdxcL/1/

【讨论】:

  • 我现在已经修复了演示的链接。
  • 谢谢!我看到你的小提琴有效,并且有明确的 'javascript:alert("It works!")' 没有不安全。但是我在我的项目中尝试过它,它仍然有 unsafe href="unsafe:javascript:alert('It works!')"。想知道有什么区别。
  • 我已将角度依赖性更新为 1.4.1 并重现。看到这个小提琴 - jsfiddle.net/ikaplin/8rm57bwf/2
  • 我会补充一个问题,角度版本是 1.4.1
  • 更新了我的答案和演示,它现在也适用于 1.4.1。似乎attrs.$set(...) 的行为在某些时候发生了变化,但解决这个问题很简单。直接在元素上设置属性值就可以了,即element[0].href = ...
猜你喜欢
  • 2016-09-22
  • 2017-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-10
  • 2015-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多