Rendering reCAPTCHA v2.0 widget within Backbone vi

2020-07-30 03:26发布

问题:

This is my issue, I have an index.html page which loads the reCAPTCHA script explicitly:

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

I have a template which contains the reCAPTCHA container element (div):

<form id="payment-<%= model.Id %>" class="form" action="" method="POST">
    ...
    <div class="captcha-container"></div> //not being used yet
</form>

And I have a backbone view which injects the template into index.thml:

'use strict';
var Backbone = require('Backbone');

var Validation = require('backbone-validation');
Backbone.Validation = Validation;
Backbone.$ = $;

module.exports = BaseView.extend({
    events: {},
    formView: null,
    initialize: function (options) {
       var loadCaptcha = function() {
            window.alert('captcha is ready');
        };
    },
    render: function () {
       // renders view using my form template
    }
});

At this point I'm unable to even trigger the callback function (loadCaptcha), my suspicion is that the issue lies in the load order, the index page is loaded and the "onload=loadCaptcha" event occurs before the backbone view is initialized. I've tried removing the "async" property from the script tag, but no luck. Any ideas of how I can get this to work?

回答1:

I figured out the solution, by pulling in the recaptcha script directly from the view which renders it. Hope this helps someone in the future.

loadCaptcha: function() {
    var self = this;
    var getRecaptchaResponse = function(response) {
      self.captchaResponse = response;
    };

    var renderCaptcha = function() {
      self.captchaWidgetId = grecaptcha.render('recaptcha-container-' + self.model.get('Id'), {
          sitekey : service.settings.recaptchaSiteKey,
          callback: getRecaptchaResponse
      });
    };

    window.renderCaptcha = renderCaptcha;

    $.getScript('https://www.google.com/recaptcha/api.js?onload=renderCaptcha&render=explicit', function() {});
},


回答2:

I would put your captch script in a backbone view. Then put it in the render of your main view. Like that it's modular you have a main view and a subview containing the captcha which is loaded when the main view is rendered.