2

所以我遇到了 svelte 和 google Recaptcha API 的问题。

我的主要 HTML 文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset='utf-8'>
    <meta name='viewport' content='width=device-width,initial-scale=1'>

    <title>Svelte app</title>

    <link rel='icon' type='image/png' href='/favicon.png'>
    <link rel='stylesheet' href='/global.css'>
    <link rel='stylesheet' href='/build/bundle.css'>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Bitter:400,700">
    <link rel="stylesheet" href="/css/styles.min.css">

    <script defer src='/build/bundle.js'></script>
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@9"></script>
</head>

<body>
</body>
</html>

我的 main.svelte

<script>
  import swal from "sweetalert";

  function verifyUser() {
    swal({
      title: "Please wait a minute!",
      text: "Do not close or exit this tab, we are currently verifying you...",
      icon: "info",
      backdrop: `rgba(0,0,0,1)`,
      showConfirmButton: false,
      allowOutsideClick: false,
      allowEscapeKey: false
    });
  }
</script>

<div>
  <div class="header-dark">
    <nav class="navbar navbar-dark navbar-expand-lg navigation-clean-search">
      <div class="container">
        <a class="navbar-brand" href="/">QSP Human Verification Module</a>
        <button class="navbar-toggler" data-toggle="collapse">
          <span class="sr-only">Toggle navigation</span>
          <span class="navbar-toggler-icon" />
        </button>
      </div>
    </nav>
    <div class="container hero">
      <div class="row">
        <div class="col-md-8 offset-md-2">
          <h1 class="text-center">
            Please complete the Captcha challenge to continue to the server.
          </h1>

          <form action="" method="post">

            <div
              class="g-recaptcha"
              data-sitekey="key"
              data-callback={verifyUser}
             />
          </form>

        </div>
      </div>
    </div>
  </div>
</div>

问题是该函数只是自身的字符串,不能仅使用"verifyUser" orverifyUser() ReCAPTCHAreturns无法找到用户提供的函数来执行:verifyUser`

using{verifyUser}变成字符串(更多https://prnt.sc/qhyc2w

像这样执行返回:

ReCAPTCHA couldn't find user-provided function: function verifyUser() {
        swal({
            title: "Please wait a minute!",
            text: "Do not close or exit this tab, we are currently verifying you...",
            icon: "info",
            backdrop: `rgba(0,0,0,1)`,
            showConfirmButton: false,
            allowOutsideClick: false,
            allowEscapeKey: false
        });
    }

汇总配置

import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';

const production = !process.env.ROLLUP_WATCH;

export default {
    input: 'src/main.js',
    output: {
        sourcemap: true,
        format: 'iife',
        name: 'app',
        file: 'public/build/bundle.js'
    },
    plugins: [
        svelte({
            // enable run-time checks when not in production
            dev: !production,
            // we'll extract any component CSS out into
            // a separate file — better for performance
            css: css => {
                css.write('public/build/bundle.css');
            }
        }),

        // If you have external dependencies installed from
        // npm, you'll most likely need these plugins. In
        // some cases you'll need additional configuration —
        // consult the documentation for details:
        // https://github.com/rollup/plugins/tree/master/packages/commonjs
        resolve({
            browser: true,
            dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/')
        }),
        commonjs(),

        // In dev mode, call `npm run start` once
        // the bundle has been generated
        !production && serve(),

        // Watch the `public` directory and refresh the
        // browser on changes when not in production
        !production && livereload('public'),

        // If we're building for production (npm run build
        // instead of npm run dev), minify
        production && terser()
    ],
    watch: {
        clearScreen: false
    }
};

function serve() {
    let started = false;

    return {
        writeBundle() {
            if (!started) {
                started = true;

                require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
                    stdio: ['ignore', 'inherit', 'inherit'],
                    shell: true
                });
            }
        }
    };
}

任何如何正确传递函数?

4

3 回答 3

3

即时通讯 Rour- 来自不和谐的家伙。我想在这里为其他人分享解决方案。

<script>
import { onMount, onDestroy } from 'svelte';

function verifyUser() {/* your fun here */}

onMount(() => {
  window.verifyUser = verifyUser;
})

onDestroy(() => {
  window.verifyUser = null;
})
</script>
<!-- then pass the name of function 'verifyUser' just as string' -->
<div class="g-recaptcha" data-sitekey="key" data-callback="verifyUser" />

考虑data-callback是搜索全局函数的名称,所以我们verifyUser在浏览器中定义为全局函数,将其分配给window变量

于 2020-01-01T05:55:13.537 回答
0

您可以在 npm 上尝试svelte-recaptcha-v2package 以获得更直接的体验。

存储库

https://github.com/basaran/svelte-recaptcha-v2

演示

https://basaran.github.io/svelte-recaptcha-v2/

PS我是包的作者。

于 2021-10-22T19:56:55.953 回答
0

如果使用 TypeScript,则需要为 Window 界面定义函数。

全球.d.t​​s

declare interface Window {
  onSubmit: (token) => void,
}

RecaptchaButton.svelte

<script lang="ts">
  import { createEventDispatcher, onMount, onDestroy } from 'svelte';
  import { variables } from '../../variables';

  const { recaptchaSiteKey } = variables;
  const dispatch = createEventDispatcher();
  type ButtonType = 'primary' | 'secondary';
  export let type: ButtonType = 'primary';

  function onSubmit(token) {
    dispatch('click', { token });
  }

  onMount(() => {
    window.onSubmit = onSubmit;
  });

  onDestroy(() => {
    window.onSubmit = null;
  });
</script>

<svelte:head>
  <script src="https://www.google.com/recaptcha/api.js" async defer></script>
</svelte:head>

<form on:submit|preventDefault={onSubmit}>
  <button
    class="g-recaptcha {type}"
    data-sitekey={recaptchaSiteKey}
    data-callback="onSubmit"
    type="submit"
  >
    Submit
  </button>
</form>

<style>
  button {
    ...
  }
  ...
</style>

ContactForm.svelte

<script>
  function handleSubmit(event) {
    console.log(event.detail.token);
    return;
  }
</script>

<RecaptchaButton on:click={handleSubmit} type="primary">Submit</ButtonRecaptcha>

如果使用类似上述的方法,您应该向 Recaptcha 按钮组件添加一个错误处理程序,您可以使用按钮上的“data-error-callback”属性;设置 Window 接口,挂载和销毁与“onSubmit”相同,但使用“onError”。

于 2021-11-05T18:42:57.423 回答