最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Invisible reCAPTCHA - Stack Overflow

programmeradmin0浏览0评论

I am working with the react-google-recaptcha to implement the invisible ReCaptcha, passing a ref to the ReCAPTCHA ponent and executing this._reCaptchaRef.current.execute() inside the ponentDidMount. showcases a form that makes use of the reCaptcha.

the onChange callback passed to the captcha ponent will set the value of the captcha into the state. The initial render the captcha value is set into the state and everything seems to work just fine, click on the submit button and the state value is printed onto the console.

After a few seconds, if we click on submit and look at the console, the value of the captcha is null. I tried to pare the value passed to onChange and if it was null I would invoke the this._reCaptchaRef.current.execute() but the issue raises when the value is null and we invoke the function but the first on submit, the value of captcha is null and every click from it will have the value in the state until it bees null.

how do I invoke the Recaptcha for the submit button and also be able to pass the value of the captcha to the callback function?

I am working with the react-google-recaptcha to implement the invisible ReCaptcha, passing a ref to the ReCAPTCHA ponent and executing this._reCaptchaRef.current.execute() inside the ponentDidMount. https://stackblitz./edit/react-invisbile-recaptcha showcases a form that makes use of the reCaptcha.

the onChange callback passed to the captcha ponent will set the value of the captcha into the state. The initial render the captcha value is set into the state and everything seems to work just fine, click on the submit button and the state value is printed onto the console.

After a few seconds, if we click on submit and look at the console, the value of the captcha is null. I tried to pare the value passed to onChange and if it was null I would invoke the this._reCaptchaRef.current.execute() but the issue raises when the value is null and we invoke the function but the first on submit, the value of captcha is null and every click from it will have the value in the state until it bees null.

how do I invoke the Recaptcha for the submit button and also be able to pass the value of the captcha to the callback function?

Share Improve this question asked Feb 6, 2020 at 9:25 visizkyvisizky 7612 gold badges11 silver badges31 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

The general idea is that the recaptcha token is valid only for a period of time. This is so that the tokens are not easily guessable by other puter systems.

Instead of doing the captcha on mount, you are supposed to execute it onSubmit only, hence the user would have filled the form when they see the captcha if at all.

handleSubmit(event) {
  event.preventDefault();
  this._reCaptchaRef.current.execute()
}

This would in turn trigger the onChange handler (or the onError handler) and you can submit the form from there.

But if you would like to somehow, keep it in ponentDidMount, you can choose to reset the captcha and execute it again.

redoCaptcha() {
  this._reCaptchaRef.current.reset();
  this._reCaptchaRef.current.execute();
}
render() {
 ...
 <ReCAPTCHA
   onExpired={this.redoCaptcha}
 />
}
import ReCAPTCHA from 'react-google-recaptcha';

const DELAY = 1500;
class Form extends React.Component {
constructor (props) {
    super(props);

    this.state = {
      value: '',
      load: false,
      expired: 'false',
      recaptchaLoaded: false
    };

    this._onSubmit = this._onSubmit.bind(this);
    this._reCaptchaRef = React.createRef();
  }

  ponentDidMount () {
    setTimeout(() => {
      this.setState({load: true});
    }, DELAY);
  }

sendData (endpoint, formData) {
    //--
    //---
    //---
    newFormData.append('recaptcha-token', this.state.value);
    //----
}

handleChange (value) {
  this.setState({value});
  if (this.state.value === null) this.setState({expired: 'true'});
}

asyncScriptOnLoad () {
  this.setState({recaptchaLoaded: true});
}

@validateAll
async _onSubmit (valid, e) {
    e.preventDefault();
    await this._reCaptchaRef.current.executeAsync();
    //----
    //---
}

render () {
    {this.state.load && googleSiteKey && (
                  <ReCAPTCHA
                    style={{display: 'inline-block'}}
                    theme="dark"
                    size="invisible"
                    ref={this._reCaptchaRef}
                    sitekey={googleSiteKey}
                    onChange={this.handleChange.bind(this)}
                    asyncScriptOnLoad={this.asyncScriptOnLoad.bind(this)}
                  />
                )}
    <button className="cta--primary" disabled={!this.state.recaptchaLoaded}>{hasForm && (<Icon icon="rightarrow" fillColor="#fff" />)}{submit}</button>
    //------
    //---
}

module.exports = Form;

//-----------------------------------------------------
//for old react version remove React.createRef();
//add below line:

import ReCAPTCHA from 'react-google-recaptcha';

const DELAY = 1500;
class Form extends React.Component {
constructor (props) {
    super(props);

    this.state = {
      value: '',
      load: false,
      expired: 'false',
      recaptchaLoaded: false
    };

    this._onSubmit = this._onSubmit.bind(this);
  }
ponentDidMount () {
    setTimeout(() => {
      this.setState({load: true});
    }, DELAY);
}
sendData (endpoint, formData) {
    //--
    //---
    //---
    const newFormData = new FormData();
    newFormData.append('recaptcha-token', this.state.value);
}

handleChange (value) {
    this.setState({value});
    if (this.state.value === null) this.setState({expired: 'true'});
}

asyncScriptOnLoad () {
    this.setState({recaptchaLoaded: true});
}

@validateAll
  async _onSubmit (valid, e) {
    e.preventDefault();
    await this.recaptchaRef.executeAsync();
    //----
    //---
}

render () {
    {this.state.load && googleSiteKey && (
                  <ReCAPTCHA
                    style={{display: 'inline-block'}}
                    theme="dark"
                    size="invisible"
                    ref={(el) => { this.recaptchaRef = el; }}
                    sitekey={googleSiteKey}
                    onChange={this.handleChange.bind(this)}
                    asyncScriptOnLoad={this.asyncScriptOnLoad.bind(this)}
                  />
                )}
    <button className="cta--primary" disabled={!this.state.recaptchaLoaded}>{hasForm && (<Icon icon="rightarrow" fillColor="#fff" />)}{submit}</button>
    //------
    //---
}
发布评论

评论列表(0)

  1. 暂无评论