反应不可见的 reCAPTCHA
React Invisible reCAPTCHA
我正在使用 react-google-recaptcha 来实现不可见的 ReCaptcha,将 ref 传递给 ReCAPTCHA 组件并在 componentDidMount 中执行 this._reCaptchaRef.current.execute()
。 https://stackblitz.com/edit/react-invisbile-recaptcha 展示了一个使用 reCaptcha 的表单。
传递给验证码组件的 onChange 回调会将验证码的值设置到状态中。初始渲染验证码值被设置为状态,一切似乎都工作正常,点击 submit 按钮,状态值被打印到控制台上。
几秒钟后,如果我们点击提交并查看控制台,验证码的值为空。我尝试比较传递给 onChange 的值,如果它为空,我将调用
this._reCaptchaRef.current.execute()
但是当值为 null 并且我们调用该函数但第一个 submit
时问题出现空。
如何为提交按钮调用 Recaptcha 并将验证码的值传递给回调函数?
大意是recaptcha token只在一段时间内有效。这是为了使令牌不容易被其他计算机系统猜到。
您应该只执行它 onSubmit
,而不是在安装时执行验证码,因此用户在看到验证码时会填写表格。
handleSubmit(event) {
event.preventDefault();
this._reCaptchaRef.current.execute()
}
这将依次触发 onChange
处理程序(或 onError
处理程序),您可以从那里提交表单。
但如果你想以某种方式保留它在componentDidMount
,你可以选择重置验证码并再次执行它。
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();
}
componentDidMount () {
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);
}
componentDidMount () {
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>
//------
//---
}
我正在使用 react-google-recaptcha 来实现不可见的 ReCaptcha,将 ref 传递给 ReCAPTCHA 组件并在 componentDidMount 中执行 this._reCaptchaRef.current.execute()
。 https://stackblitz.com/edit/react-invisbile-recaptcha 展示了一个使用 reCaptcha 的表单。
传递给验证码组件的 onChange 回调会将验证码的值设置到状态中。初始渲染验证码值被设置为状态,一切似乎都工作正常,点击 submit 按钮,状态值被打印到控制台上。
几秒钟后,如果我们点击提交并查看控制台,验证码的值为空。我尝试比较传递给 onChange 的值,如果它为空,我将调用
this._reCaptchaRef.current.execute()
但是当值为 null 并且我们调用该函数但第一个 submit
时问题出现空。
如何为提交按钮调用 Recaptcha 并将验证码的值传递给回调函数?
大意是recaptcha token只在一段时间内有效。这是为了使令牌不容易被其他计算机系统猜到。
您应该只执行它 onSubmit
,而不是在安装时执行验证码,因此用户在看到验证码时会填写表格。
handleSubmit(event) {
event.preventDefault();
this._reCaptchaRef.current.execute()
}
这将依次触发 onChange
处理程序(或 onError
处理程序),您可以从那里提交表单。
但如果你想以某种方式保留它在componentDidMount
,你可以选择重置验证码并再次执行它。
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();
}
componentDidMount () {
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);
}
componentDidMount () {
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>
//------
//---
}