【问题标题】:Google captcha with svelte带有苗条的谷歌验证码
【发布时间】:2020-04-20 03:23:01
【问题描述】:

所以我在使用 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()returnsReCAPTCHA 找不到用户提供的函数:verifyUser`

使用{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
                });
            }
        }
    };
}

如何正确传递函数?

【问题讨论】:

  • 是你截图上的捆绑代码吗?
  • 这很奇怪,如果您查看this RELP 的输出,verifyUser 函数应该被赋予data-callback 属性:attr(div1, "data-callback", verifyUser);。如果我理解您的问题 - 在您的 main.svelte 中,您将 verifyUser 函数传递给 data-callback,那么当您捆绑代码并在导航器中检查它时,您的函数变成了字符串?
  • 是的,{verifyUser} 不应成为字符串。我做了一些研究,我发现如果在事件之前使用on:,事件会起作用,现在的问题是如果我输入on:data-callback={verifyUser},它什么也不做。我的理解是,还有其他方法可以告诉 svelte 这是一个函数而不是字符串(或者不将其转换为字符串)。我不确定如何正确执行此操作,因此当用户完成验证码时,它会执行该功能
  • 我不认为这是因为你的语法,我认为这是来自你的捆绑器。你用的是哪一个?您可以编辑您的问题并在其中添加配置文件吗?

标签: javascript google-apps-script svelte-3


【解决方案1】:

我是 Rour——来自 discord 的那个人。我想在这里为其他人分享解决方案。

<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变量

【讨论】:

    【解决方案2】:

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

    存储库

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

    演示

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

    P.S 我是包的作者。

    【讨论】:

      【解决方案3】:

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

      global.d.ts

      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"。

      【讨论】:

        猜你喜欢
        • 2016-08-04
        • 1970-01-01
        • 1970-01-01
        • 2012-03-02
        • 2016-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多