Используйте AJAX для перезагрузки капчи

Возможно, этот вопрос уже задавался, но, к сожалению, удовлетворительных ответов я не нашел. Я просто спрошу его для своего конкретного случая и попрошу админов не удалять вопрос хотя бы несколько дней, чтобы я мог попробовать...

У меня есть страница. Он использует капчу. Вот так:

<?php
session_start(); // the captcha saves the md5 into the session
?>
<img src="captcha.php" onclick="this.src = this.src" />

Это был мой первый код. Это не сработало, потому что браузер посчитал бесполезным перезагружать изображение, если исходник тот же. Мое текущее решение - передать параметр get:

onclick="this.src = 'captcha.php?randomNumber='+ranNum"

Переменная JavaScript var ranNum генерируется случайным образом каждый раз, когда срабатывает событие onclick. Это работает нормально, тем не менее, мне не нравится возможность, если - хотя и маловероятно - случай, когда два числа совпадают дважды подряд. Хотя случайное число колеблется между -50 000 и 50 000 - мне все равно это не нравится. И я не думаю, что метод является правильным. Я хотел бы знать более «правильный» метод с помощью AJAX. Я знаю, что это возможно. Надеюсь, вы знаете, как это возможно ^^ В таком случае, пожалуйста, покажите мне.

Заранее спасибо!

Кстати, если я напишу cap(t)cha по-другому, ничего страшного, ссылка на файл PHP будет прямо в моем коде: я использую randomImage.php

РЕДАКТИРОВАТЬ: случайное число в JavaScript генерируется только для перезагрузки изображения. Captcha.php не заботится о параметре $_GET. Строка действительно случайная.

РЕДАКТИРОВАТЬ: Таким образом, я хотел бы знать, как заставить браузер перезагружать изображение, не передавая разные параметры получения каждый раз, когда событие срабатывает.


person arik    schedule 15.05.2010    source источник
comment
Да, я думаю, нет ничего важнее чтения книг ;)   -  person arik    schedule 14.07.2012


Ответы (4)


К сожалению, AJAX не предоставляет возможности динамической загрузки изображений. Даже использование javascript-трюка с предварительной загрузкой просто заставляет браузер загружать каждое изображение один раз для каждого URL-адреса. Единственный хороший способ заставить браузер загрузить другое изображение из того же источника — использовать другой параметр, как вы делаете сейчас. И, как указано в других ответах, для этого должно быть достаточно метки времени.

person Eric Mickelsen    schedule 15.05.2010
comment
Что ж... очень жаль. Спасибо. - person arik; 16.05.2010
comment
Похоже, что это выходит за рамки языка (PHP) и входит в рамки веб-сервера. Я не пробовал, но я думаю, что если вы используете apache, вы могли бы использовать какой-нибудь модуль, например [rewrite] (https://httpd.apache.org/docs/2.4/rewrite/remapping.html), чтобы сопоставить любой запрос, скажем, /captcha* с вашим php, тем самым устраняя необходимость в параметре get . Это если вы также администрируете веб-сервер и это apache. С другими серверами могут быть и другие способы. - person dabicho; 29.09.2016

Рассматривали ли вы вместо этого использование временной метки?

onclick="this.src='captcha.php?ts='+Math.round(new Date().getTime()/1000)"
person karim79    schedule 15.05.2010
comment
это звучит интересно. не было бы риска повторения номера. тем не менее, я хотел бы знать, как это делается с помощью AJAX ^^ - person arik; 16.05.2010
comment
Это асинхронно и использует JS, следовательно, это AJAX. - person nico; 16.05.2010
comment
@Nico: нет XML, и он не использует XMLHttpRequest, поэтому технически это не AJAX. Браузер просто загружает изображение, когда обнаруживает новый источник. - person Eric Mickelsen; 16.05.2010
comment
Вы можете вызвать сервер для отправки нового источника изображения, который будет временной меткой, сгенерированной сервером, например. onclick="captcha.php?ts=<?php echo time() ?>". Тем не менее, я не вижу никакой реальной пользы в том, чтобы делать это таким образом, это похоже на другой способ сделать то же самое. - person karim79; 16.05.2010
comment
это не сработает. time() будет сгенерирован один раз заранее, но позже он будет таким же, поэтому источник не изменится и изображение не перезагрузится. - person arik; 16.05.2010
comment
@arik-так, ты меня неправильно понял. Я имел в виду, что при щелчке клиент отправляет запрос XHR и извлекает новый источник, который является либо тем же самым с добавленной отметкой времени, либо вообще новым именем исходного файла, что я имел в виду, вызывая сервер. Я должен был быть более ясным... - person karim79; 16.05.2010
comment
@tehMick: ну ... это действительно придирки;) Хорошо, технически это не AJAX, но это асинхронная загрузка изображения. Конечно, для этого можно использовать XMLHttpRequest, но на самом деле это не принесет никакой пользы. PS: Я не согласен с тем, что AJAX требует XML, это только в названии, но очень часто используются другие типы ответов. Например, мне нравится, чтобы мои вызовы AJAX возвращали JSON, с которым мне проще работать в JS, чем в XML. - person nico; 16.05.2010
comment
@nico - На самом деле вам было бы трудно использовать XMLHttpRequest для фактической загрузки изображения - это, вероятно, возможно, но слишком много для OP. Вы правы, многие AJAX вместо этого используют JSON, но изменение источников изображений с помощью javascript предшествует появлению AJAX на несколько лет, поэтому я не думаю, что это соответствует требованиям. - person Eric Mickelsen; 16.05.2010
comment
@tehMick: нет, нет, я не предлагал использовать XMLHttpRequest (хотя я думаю, что это технически осуществимо)!!! Тот факт, что перезагрузка исходников была возможна еще до изобретения AJAX, не делает его менее асинхронным :) Он загружает изображение с сервера ПОСЛЕ загрузки страницы, вот и все. Учтите, что XMLHttpRequest восходит к 2000 году, за 5 лет до изобретения термина AJAX (2005 год)!!! Так что технически AJAX, возможно, существовал еще до того, как этот термин даже придумали! :D - person nico; 16.05.2010

Просто используйте:

<img src="captcha.php" onclick='this.src = "captcha.php&time=" + new Date().getTime();' />

Вы можете отказаться от параметра времени и сгенерировать случайное число в PHP. :)

person nico    schedule 15.05.2010
comment
Благодарю. Извините, вопрос не ясен, я игнорирую параметр get. Он используется только для того, чтобы заставить браузер перезагрузить изображение ;) Тем не менее, я хотел бы знать, как я могу заставить браузер перезагрузить изображение БЕЗ передачи случайного параметра получения. - person arik; 16.05.2010
comment
@arik-so Насколько я знаю, это невозможно сделать. Если браузер увидит, что src изображения тот же, он не будет перезагружать его. Недавно я изучал аналогичную проблему, и это почти единственное решение, которое я нашел. Конечно, если кто-то знает другой вариант, я был бы очень рад узнать об этом! - person nico; 16.05.2010
comment
хорошо, я подожду и оставлю вопрос открытым. Может кто найдет ответ. - person arik; 16.05.2010

Вы также можете получить изображение из запроса Ajax в кодировке base64 и поместить его в тег img.

Конечно, я думаю, что это излишество, и файл с кодировкой base64 составляет около 4/3 размера оригинала. (Изображение размером 3 КБ будет весить около 4 КБ в base64).

Изменить: чтобы иметь атрибут img src, например

данные: изображение/png; base64, base64encodedimage

person dabicho    schedule 31.05.2016