2016-02-29 156 views
1

我使用angularjs和html2canvas捕獲屏幕截圖。它在少數幾個屏幕上很好地捕捉,並且不會有時。我得到以下錯誤:angularjs unsafe:data;當使用html2canvas捕獲屏幕截圖

enter image description here 試圖Angular changes urls to "unsafe:" in extension page並加入我的config.js

app.config(['$compileProvider', function ($compileProvider) { 
    $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|local|data):/); 
}]); 

它有助於我不是得到不安全的程度以下內容:數據;單擊我的圖像捕捉按鈕時會出錯,但圖像也不會被捕捉到。 現在的HTML標記看起來如下:

<img ng-src="data:," class="img-responsive" src="data:,"> 

,而不是實際的base64網址爲我的圖像/ PNG(例如:<img ng-src="data:image/png;base64,Mybase64Url)。 我在我的index.html中添加了ng-csp指令,並將每個<img src="">更改爲<img ng-src="">

相機form.html:

<form name="captureForm" ng-submit="ctrl.save()"> 
    <div class="modal-header"> 
     <h3 class="modal-title">Captured Screen shot</h3> 
    </div> 
    <div class="modal-body"> 
     <div class="container-fluid padding"> 
      <div class="row"> 
       <div class="col-sm-8"> 
        <img ng-src="{{ctrl.imageURL}}" class="img-responsive" id="capturedImage"> 
       </div> 
       <div class="col-sm-4"> 
        <div class="form-group"> 
         <input placeholder="Title" name="title" required class="form-control" ng-model="ctrl.title"> 

         <div ng-show="captureForm.$submitted || captureForm.title.$dirty" 
          ng-messages="captureForm.title.$error"> 
          <div ng-message="required">Title is required</div> 
         </div> 
        </div> 

        <div class="form-group"> 
         <select name="category" ng-model="ctrl.category" class="form-control" required> 
          <option value="1">Knowledge</option> 
          <option value="2">Irregular</option> 
          <option value="3">Periodic maintenance</option> 
         </select> 
         <div ng-show="captureForm.$submitted || captureForm.category.$dirty" 
          ng-messages="captureForm.category.$error"> 
          <div ng-message="required">Category is required</div> 
         </div> 
        </div> 

        <div class="form-group"> 
        <textarea placeholder="Comment" name="comment" required class="form-control" 
           ng-model="ctrl.comment"></textarea> 

         <div ng-show="captureForm.$submitted || captureForm.comment.$dirty" 
          ng-messages="captureForm.comment.$error"> 
          <div ng-message="required">Comment is required</div> 
         </div> 
        </div> 
       </div> 
      </div> 
     </div> 
    </div> 

    <div class="modal-footer"> 
     <input type="submit" class="btn btn-info" value="Save"> 
     <a href ng-click="ctrl.cancel()" class="btn btn-danger">Cancel</a> 
    </div> 
</form> 

camera.directive.js:

(function() { 
    'use strict'; 

    angular 
     .module('myModule') 
     .directive('camera', camera); 

    camera.$inject = ['$rootScope']; 

    /* @ngInject */ 
    function camera($rootScope) { 
     var directive = { 
      link: link, 
      restrict: 'A' 
     }; 

     return directive; 

     function link(scope, element, attrs) { 
      $rootScope.$on('capture', function (event, deferred) { 
       event.stopPropagation(); 

       renderSvg(element); 

       //method to render the SVG's using canvg 
       function renderSvg(element) { 
        // First render all SVGs to canvases 
        var elements = element.find('svg').map(function() { 
         var svg = $(this); 
         var canvas = $('<canvas></canvas>'); 
         svg.replaceWith(canvas); 

         // Get the raw SVG string and curate it 
         var content = svg.wrap('<p></p>').parent().html(); 
         content = content.replace(/xlink:title="hide\/show"/g, ""); 
         content = encodeURIComponent(content); 
         svg.unwrap(); 

         // Create an image from the svg 
         var image = new Image(); 
         image.src = 'data:image/svg+xml,' + content; 
         image.onload = function() { 
          canvas[0].width = image.width; 
          canvas[0].height = image.height; 

          // Render the image to the canvas 
          var context = canvas[0].getContext('2d'); 
          context.drawImage(image, 0, 0); 
         }; 
         return { 
          svg: svg, 
          canvas: canvas 
         }; 
        }); 

         // At this point the container has no SVG, it only has HTML and Canvases. 
         html2canvas(element[0], { 
          useCORS: true, 
          allowTaint: true, 
          onrendered: function (canvas) { 
           // Put the SVGs back in place 
           elements.each(function() { 
            this.canvas.replaceWith(this.svg); 
           }); 

           var dataURL = null; 

           try { 
            dataURL = canvas.toDataURL("image/png", 0.9); 
            deferred.resolve(dataURL); 
           } 
           catch (e) { 
            deferred.reject(e); 
           } 
          } 
         }); 
       } 
      }); 
     } 
    } 
})(); 

camera.controller.js:

/** 
* CameraController.js 
*/ 
(function() { 
    'use strict'; 

    angular 
     .module('myModule') 
     .controller('CameraController', CameraController); 

    CameraController.$inject = ['$rootScope', 'cabinetService', 'SweetAlert', 'growl', '$q', '$uibModal', 'spinner']; 

    function CameraController($scope, cabinetService, SweetAlert, growl, $q, $uibModal, spinner) { 

     var ctrl = this; 

     ctrl.captureScreenShot = captureScreenShot; 

     function captureScreenShot($event) { 
      var deferred = $q.defer(); 

      $scope.$emit('capture', deferred); 

      deferred.promise.then(uploadScreenShot); 
     } 

     function uploadScreenShot(imageURL) { 
      var modalInstance = $uibModal.open({ 
       animation: true, 
       templateUrl: 'app/components/capture/camera-form.html', 
       controller: ModalCtrl, 
       controllerAs: 'ctrl', 
       size: 'lg', 
       resolve: { 
        imageURL: function() { 
         return imageURL; 
        } 
       } 
      }); 

      modalInstance.result.then(function (captureData) { 
       var data = { 
        Base64Url: captureData.image.split(',')[1], 
        Title: captureData.title, 
        FileCategory:parseInt(captureData.category), 
        Comment: captureData.comment, 
        FunctionalityName: $scope.$state.current.name 
       }; 

       spinner.spinnerShow(); 

       //call the service to upload the screen shot 
       cabinetService 
        .uploadScreenShot(data) 
        .then(function (data) { 
         SweetAlert.swal({ 
           title: 'Screen shot saved successfully!', 
           text: '', 
           type: 'info', 
           showCancelButton: true, 
           confirmButtonColor: '#DD6B55', 
           confirmButtonText: 'Open cabinet', 
           closeOnConfirm: true 
          }, 
          function (isConfirm) { 
           if (isConfirm) { 
            $scope.$state.go('index.cabinet') 
           } 
          }); 
        }) 
        .catch(function (err) { 
         SweetAlert.swal("Cannot capture the screen shot", "Something went wrong, please try again !", "error"); 
         growl.err('Unable to upload the screen shot', {ttl: 20000}); 
        }) 
        .finally(spinner.spinnerHide); 
      }, function() { 
       $log.info('Modal dismissed at: ' + new Date()); 
      }); 
     } 
    } 

    ModalCtrl.$inject = ['$scope', '$uibModalInstance', 'imageURL', 'growl']; 

    function ModalCtrl($scope, $uibModalInstance, imageURL, growl) { 
     var ctrl = this; 

     ctrl.imageURL = imageURL; 
     ctrl.save = save; 
     ctrl.cancel = cancel; 

     function activate() { 
     } 

     function save() { 
      var form = $scope.captureForm; 

      if (form.$dirty && form.$valid) { 
       $uibModalInstance.close({ 
        image: imageURL, 
        title: ctrl.title, 
        comment: ctrl.comment, 
        category: ctrl.category 
       }); 
      } else { 
       growl.info('Please fill out all the fields'); 
      } 
     } 

     function cancel() { 
      $uibModalInstance.dismiss(); 
     } 
    } 
}()); 

有什麼我需要做的與上述正則表達式或我缺少別的東西?請幫忙 !

回答

0

由於某些原因,在點擊時作爲$ event參數傳遞的元素不會每次傳遞正確的div元素。而是通過我想要的元素的確切的div元素,它的工作。

1

嗨,你需要使用jQuery來改變形象src屬性爲

$("#canvas_image").attr("src", canvasdata);

我有這個Plunker

在此plunker,如果你想使用它,我已經加指令以及嘗試。

+0

非常感謝Shankar,但我認爲我的代碼已經以不同的方式使用ng-src來完成屬性綁定。我在上面的文章中添加了我的代碼。你可以看一下嗎?除了有時圖像沒有被捕獲,一切都在工作。謝謝 ! – Srini

+0

你在哪裏使用過'camera'指令?以及如何捕捉事件正在廣播?請提供相關代碼進行檢查。 –

+0

我有一個名爲topnavbar.html的文件,其中im使用相機指令和控制器,如下所示:

  • Srini