-->

Change dynamically Recaptcha V2 language

2019-04-24 01:40发布

问题:

I trying to implement Recaptcha V2 on an angular site.

I'm using angular translate and I don't know how to regenerate the reCaptcha object with the correct language provided from the $scope

There is any method ? or process to reload the object with the correct lang ?

Thanks

回答1:

Based on the limitation of the API you can load the script dynamically:

Function to load script

(source)

function loadScript(url, callback)
{
    // Adding the script tag to the head as suggested before
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;

    // Then bind the event to the callback function.
    // There are several events for cross browser compatibility.
    script.onreadystatechange = callback;
    script.onload = callback;

    // Fire the loading
    head.appendChild(script);

   //modification so we can remove this after
   return script;
}

Note: this is a regular JS function

Load script dynamically

in your Angular controller

 $scope.loadGoogleRecaptcha = function (id, lang) {
            /// using timeout not to use $apply
            $timeout(function () {
                //set default value
                var elemntID = id || false;
                var language = lang || 'en';

                if (!elemntID) {
                    console.warn('NO Id selected for re-captcha loading!')
                    return false;
                }

                var element = document.getElementById(elemntID)
                if (angular.element(element).length == 0) {
                    console.warn('provided id doesn\'t exist ', elemntID);
                    return false;
                }

                //Delete oldscript
                if ($rootScope.addedScript)
                    angular.element($rootScope.addedScript).remove();

                //clear current recaptcha container
                angular.element(element).empty();

                var url = "https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit&hl=" + lang;

                return $window.loadScript(url, function () {
                    console.log('Scipt loaded:', url);
                })

            });

        }

init captcha with current language using angular-translate-localStorage

$rootScope.addedScript = $scope.loadGoogleRecaptcha('g-recaptcha-register' ,$window.localStorage.getItem( 'NG_TRANSLATE_LANG_KEY'));

sample of function to switch language

$rootScope.changeLanguage = function (langKey) {

        $translate.use(langKey);
        $rootScope.selectedLanguage = langKey;
        $scope.loadGoogleRecaptcha('g-recaptcha-register' , langKey);
    };

Or you could use a watcher

 $scope.$watch(
            'selectedLanguage', function (n, o) {
              //putting if to prevent double fetch the first time
              if (!!n && n != o){
                $rootScope.addedScript = $scope.loadGoogleRecaptcha('g-recaptcha-register', n);
              }
            }
        );


回答2:

Changing the recapacha src with the right hl attribute worked for me

Heres my solution using JQuery

// reload capcha on translation
$rootScope.$on('$translateChangeSuccess', (event, data) => {
  // reload captcha
  let language;

  if (data.language === 'en_CA') {
    language = 'en';
  } else {
    language = 'fr';
  }
  const captchaElm = angular.element(document).find('.vc-recaptcha').find('iframe');
  if (captchaElm.length) {
    let src = captchaElm.attr('src');
    src = src.replace(/(hl=)[^\&]+/, `$1${language}`);
    captchaElm.attr('src', src);
  }
});