javascript 在 angularJS 中集成验证码的最佳方式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30301971/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 12:01:04  来源:igfitidea点击:

Best way to integrate captcha in angularJS

javascriptangularjsformsangularjs-directivecaptcha

提问by sengbatz

I'm relatively new to angularJS and I wonder what would be the cleanest solution to the following problem. Let's say I have a form such as follows

我对 angularJS 比较陌生,我想知道以下问题的最干净的解决方案是什么。假设我有一个如下形式

<form name="contactform">
   <select id="salutation" name="salutation" required="true" ng-model="contactRequest.salutation"><option value="Herr" selected="">Herr</option><option value="Frau">Frau</option></select>

   <img width="255" height="70" alt="" src="/website/var/tmp/aed4d639a26c4614cdac2a967381c61c.png" name="captcha[img]"> 

   <captcha-reloader reload-url="/refresh-captcha" img-tag-name="captcha[img]" hidden-field-name="captcha[id]"></captcha-reloader>

   <input type="text" name="captcha[input]" required="true" ng-model="contactRequest.captcha.input">                

   <input type="text" style="display: none;" ng-model="contactRequest.captcha.id" value="aed4d639a26c4614cdac2a967381c61c" name="captcha[id]">   
...

As you can see, it uses a directive to display a button which will reload the CAPTCHA. It is defined as

如您所见,它使用一个指令来显示一个按钮,该按钮将重新加载 CAPTCHA。它被定义为

    myApp.directive('captchaReloader', function () {
    return {
        restrict: 'E',
        scope: {
            reloadUrl: '@',
            imgTagName: '@',
            hiddenFieldName: '@'
        }, //isolate scope
        template: '<a href="" ng-click="reloadCaptcha()" class="captcha-reload"></a>',
        link: function (scope, element, attrs) {

        },
        controller: function ($scope, $element, $attrs, $http) {
            $scope.reloadCaptcha = function () {
                $http.get($attrs.reloadUrl).then(function (res) {
                    angular.element('img[name="' + $attrs.imgTagName + '"]').attr('src', res.data.imgSrc);
                    angular.element('input[name="' + $attrs.hiddenFieldName + '"]').val(res.data.id);
                    angular.element('input[name="' + $attrs.hiddenFieldName + '"]').trigger('input');
                });
            };
        }
    };
)};

If I click on the button, the captcha image and value (hidden field) are updated. It works fine so far.

如果我点击按钮,验证码图像和值(隐藏字段)会更新。到目前为止它运行良好。

Now, I want to handle form submission in controller (see methode below). If there is an error (server-side validation), the captcha has to be updated. I don't know whats the best way to trigger the updated-process defined in the directive. Can anyone help?

现在,我想在控制器中处理表单提交(参见下面的方法)。如果出现错误(服务器端验证),则必须更新验证码。我不知道触发指令中定义的更新进程的最佳方法是什么。任何人都可以帮忙吗?

    myApp.controller('KontaktCtrl', function ($scope, $location, CustomerDataService, CaptchaService) {
    $scope.contactRequest = {
        salutation: 'Herr',
        captcha: {
            id: initialCaptchaId
        }
    };
    $scope.errors = {};

    $scope.submitAction = function () {
        CustomerDataService.sendRequest($scope.contactRequest).then(function (res) {
            var data = res.data;
            if (res.data.data !== null) { //errors in form. Display them
                //error handling
                $scope.reloadCaptcha();
            } else {
                goToHomeView();
            }
        }, function (error) {
            console.log('An error occurred while updating!', error);
        });
    };


    var goToHomeView = function () {
        $location.path('/');
    };
});

Additionally, I have to init the values of select-box and captcha, cause otherwise they are not sent (because the are untouched). Is there any way to avoid this?

此外,我必须初始化 select-box 和 captcha 的值,否则它们不会被发送(因为它们没有被修改)。有什么办法可以避免这种情况吗?

PS: I found a reCAPTCHA directive, but reCAPTCHA is no option due to styling limitations.

PS:我找到了一个 reCAPTCHA 指令,但由于样式限制,reCAPTCHA 不是选项。

回答by Kaushik Das

Its very simple follow the steps...

它非常简单,按照步骤...

<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
async defer></script>

<script>
    var onloadCallback = function() {
        widgetId1 = grecaptcha.render('example1', {
            'sitekey' : 'Site-Key-',
            'theme' : 'light'
        });
    };
</script>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
async defer>

Now at the form put it

现在在表格上放它

<div id="example1"></div> 
<p style="color:red;">{{ captcha_status }}</p>

Validate with angular

用角度验证

if(grecaptcha.getResponse(widgetId1)==''){
    $scope.captcha_status='Please verify captha.';
    return;
}