Polymer 3.0 重新验证 google

Polymer 3.0 recaptcha google

目前我使用的是 polymer 3.0 版,我尝试实现 recaptcha v2,但是加载脚本时出现问题:<script src="https://www.google.com/recaptcha/api.js" async defer></script>,polymer 无法在 shadow dom 中加载脚本。我在这里找到了用于验证码的 webcomponent:https://www.webcomponents.org/element/Zecat/google-recaptcha,但它只支持 polymer 的版本 1 和 2.x。有没有办法在 Polymer 3.0 中实现 recaptcha(checkbox)?

我发现的技巧是在 运行 时间内创建必要的脚本标签并将脚本附加到文档头部或正文以显示 reCAPTCHA 元素。在 firstUpdated() 方法上执行此操作 请按照以下步骤操作:

1: 为 google recaptcha 创建脚本标签 api

 var script = document.createElement( 'script' );
script.src= 'https://www.google.com/recaptcha/api.js';
script.async = true; 
script.defer = true;
  1. 将脚本附加到文件头document.head.appendChild(script);

  2. 也在 运行 时间内创建 div 来托管 reCAPTCHA 并将其附加到正文,因为它不会显示在 shadowRoot

var recaptcha = document.createElement('div');
        recaptcha.setAttribute('class','g-recaptcha');
        recaptcha.setAttribute('data-theme','light');
        recaptcha.setAttribute('data-callback','recaptchaCallback');
        recaptcha.setAttribute('data-sitekey','site_key');
        //attaching recaptcha element to document body
        document.body.appendChild(recaptcha);

此时 recaptcha 元素将显示在文档上。但唯一的问题是它所在的位置。所以这里的问题是如何将它显示到 DOM 上加载 shdadowRoot 的位置。破解方法是在 运行 时间内获取 shadowRoot 的位置,并将样式属性附加到我们刚刚创建的 recaptcha div,我们将位置设置为 absoulte postion:absolute并根据 shadowRoot 所在的位置添加 bottom 和 left 位置。它看起来像这样:

let rBody =this.shadowRoot.querySelector("#rBody"); //element in the shadowRoot

let topPosition = rBody.getBoundingClientRect().top;
let leftPosition = rBody.getBoundingClientRect().left;

recaptcha.setAttribute('style','position:absolute;top:'+ topPosition+ 'px;'+ 'left:'+ leftPosition + 'px;');

此时 recaptcha 应该已经相应地定位了自己。希望您正在使用的表单没有动画,因为验证码将始终保持在原位,但它有效。

所以另一个关键因素是知道recaptcha的验证是否成功。我们还必须为此做另一次黑客攻击。为此,我们还在 运行 时间创建了一个脚本标签,并且它的文本内容嵌入了一个函数,该函数将由 google 的 data-callback 属性调用].回调函数仅在成功时调用,这对我们来说已经足够了。有关更多信息,请查看文档 here 它应该看起来像这样:

recaptcha.setAttribute('data-callback','recaptchaCallback');
//script for callback
    let callBackScript =  document.createElement( 'script' );
    callBackScript.textContent = ' function recaptchaCallback(){var recapValue = document.createElement("p"); recapValue.setAttribute("id","recapValue"); recapValue.setAttribute("pass","r-true");document.body.appendChild(recapValue);console.log("Recaptcha callback passed");}';

    document.body.appendChild(callBackScript);

回调函数 我也在创建一个 p 元素并设置一个自定义属性,如果该元素实际创建,则表示验证成功,您可以通过创建一个检查方法来确认如果创建的元素,在本例中为 p 如果其在 dom 上 by :

 let recaptchaValue = document.querySelector('#recapValue');
    if(recaptchaValue !=null){
      return recaptchaValue.getAttribute("pass");
    }else{
      return null; 
    }

希望这对您有所帮助。不幸的是,对于 Polymer 3.0,我们不得不求助于这些技巧,因为没有针对我们特定用例的节点包。