angularjs不安全:数据;使用html2canvas捕获屏幕截图时

时间:2016-02-29 17:50:49

标签: javascript html angularjs base64 html2canvas

我正在使用angularjs和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:,">

而不是我的image / png的实际base64网址(例如:<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();
        }
    }
}());

我有什么需要处理上面的正则表达式或我错过了其他东西?请帮忙!

2 个答案:

答案 0 :(得分:1)

您好需要使用jquery改变image src属性

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

我试过这个Plunker

在这个plunker中,如果你想使用它,我也添加了指令。

答案 1 :(得分:0)

由于某种原因,在click上作为$ event参数传递的元素不是每次都传递正确的div元素。而是在元素的位置传递了我想要的精确div元素,并且它起作用。