How to create Ajax refresh for django-simple-captcha

喜夏-厌秋 提交于 2020-06-22 12:06:29

问题


I'm using the django-simple-captcha app for my django based website, I am able to integrate the captcha form field into my form, but the problem is, how do I create a button which calls Ajax refresh to refresh the captcha image on click? The documentation for the app is not very clear, and I tried to follow the example given in the documentation but it doesn't work. Please help me on this issue?

EDIT: Here's the link to the django package: django-simple-captcha


回答1:


Here's a working implementation in javascript:

$(function() {
    // Add refresh button after field (this can be done in the template as well)
    $('img.captcha').after(
            $('<a href="#void" class="captcha-refresh">Refresh</a>')
            );

    // Click-handler for the refresh-link
    $('.captcha-refresh').click(function(){
        var $form = $(this).parents('form');
        var url = location.protocol + "//" + window.location.hostname + ":"
                  + location.port + "/captcha/refresh/";

        // Make the AJAX-call
        $.getJSON(url, {}, function(json) {
            $form.find('input[name="captcha_0"]').val(json.key);
            $form.find('img.captcha').attr('src', json.image_url);
        });

        return false;
    });
});

Then you just need to add some CSS for the class captcha-refresh, perhaps place an image in the <a> and you're good to go!




回答2:


The chosen answer is with jQuery not JavaScript.

If using purely JavaScript you should do this instead. This will also refresh the audio not just the image django-simple-captcha uses.

https://django-simple-captcha.readthedocs.io/en/latest/advanced.html#rendering

FORM_RENDERER = 'django.forms.renderers.TemplatesSetting'

custom_field.html:

    ​
{% load i18n %}
{% spaceless %}

  <label class="control-label">{{ label }}</label>
        <img src="{{ image }}" alt="captcha" class="captcha" />
<br/>
<audio id="audio" controls>
  <source id="audioSource" src="{{ audio }}" />
</audio>
      {% include "django/forms/widgets/multiwidget.html" %}
{% endspaceless %}

Forms.py:

    ​
    class CustomCaptchaTextInput(CaptchaTextInput):
        template_name = 'custom_field.html'
    ​
    class Form(forms.Form):
        captcha = CaptchaField(widget=CustomCaptchaTextInput)
    ​
        def __init__(self, *args, **kwargs):
            super(Form, self).__init__(*args, **kwargs)
            self.fields['captcha'].widget.attrs['placeholder'] = 'Solve the captcha'
            self.fields['captcha'].label = "Captcha"

Add this at the end of the body tag:

<script>
const captchas = document.querySelectorAll('img.captcha')

function headers(options) {
  options = options || {}
  options.headers = options.headers || {}
  options.headers['X-Requested-With'] = 'XMLHttpRequest'
  return options
}

for (const captcha of captchas) {
  const anchor = document.createElement('a')
  anchor.href = '#void'
  anchor.classList.add('captcha-refresh')
  anchor.textContent = 'Refresh'
  anchor.addEventListener('click', ({ target }) => {
    const url = `${window.location.origin}/captcha/refresh/`
    let formEl = target.parentElement

    while (formEl && formEl.tagName.toLowerCase() !== 'form') {
      formEl = formEl.parentElement
    }

    fetch(url, headers())
      .then(res => res.json())
      .then(json => {
        formEl.querySelector('input[name="captcha_0"]').value = json.key
        captcha.setAttribute('src', json.image_url)
        document.getElementById('audioSource').setAttribute('src', json.audio_url)
        document.getElementById('audio').load()
      })
      .catch(console.error)

    return false
  })

  captcha.after(anchor)
}
</script>


来源:https://stackoverflow.com/questions/18972515/how-to-create-ajax-refresh-for-django-simple-captcha

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!