使用 AJAX 重新加载验证码

3
这个问题可能已经被问过了,但是很遗憾,我没有找到令人满意的答案。我将为我的具体情况提出这个问题,并请求管理员不要在至少几天内删除该问题,以便我可以尝试一下...
我有一个页面。它使用验证码。就像这样:
<?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参数。字符串确实是随机的。

编辑:因此,我想知道如何使浏览器在每次事件触发时重新加载图像,而不必传递不同的get参数。


是的,我想没有什么比阅读书籍更重要了 ;) - arik
4个回答

5

不幸的是,AJAX没有提供一种良好的动态加载图像的方法。即使使用JavaScript的“预加载”技巧,浏览器也只会每个URL加载一次每个图像。唯一一个从同一来源获取浏览器加载另一张图片的好方法就是像现在这样使用不同的参数。正如其他答案所述,时间戳应该足够。


嗯...那真是太不幸了。谢谢。 - arik
看起来这超出了语言(PHP)的范畴,而是在Web服务器的范畴内。我没有尝试过,但我认为如果你使用Apache,你可以使用一些模块,比如rewrite,将任何请求映射到,比如/captcha*,进入你的PHP,从而消除了对GET参数的需求。这是在你也管理Web服务器且它是Apache的情况下。其他服务器可能有其他方法。 - dabicho

3
你考虑过使用时间戳吗?
onclick="this.src='captcha.php?ts='+Math.round(new Date().getTime()/1000)"

这是异步的,并且利用了JS,因此它是AJAX。 - nico
1
@Nico:没有使用XML,也没有使用XMLHttpRequest,因此它在技术上不算是AJAX。当浏览器检测到新的源时,它只是为您加载图像。 - Eric Mickelsen
1
这样做是行不通的。time()会在之前生成一次,但后来它会保持不变,因此源代码不会改变,图片也不会重新加载。 - arik
@nico - 实际上,使用XMLHttpRequest来加载图像可能会很困难 - 这可能是可行的,但对于OP来说过于繁琐。你是对的,“AJAX”使用JSON的情况很多,但使用JavaScript更改图像源的方法比AJAX出现早几年,因此我认为它不符合条件。 - Eric Mickelsen
@tehMick:不,我并没有建议使用XMLHttpRequest(尽管从技术上讲可能是可行的)!!!即使在AJAX发明之前,重新加载资源仍然是可能的,这并不会减少它的异步性 :)他正在载入页面加载后从服务器加载图像,就是这样。请注意,XMLHttpRequest可以追溯到2000年,比AJAX术语(2005年)甚至还要早五年!!所以从技术上讲,在甚至没有想到这个术语之前,AJAX就有可能出现了!:D - nico
显示剩余4条评论

1

只需要使用:

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

您可以舍弃时间参数并在PHP中生成随机数。 :)


谢谢。非常抱歉,问题不够清晰,我确实忽略了获取参数。它只是用来强制浏览器重新加载图片的 ;) 不过,我仍然想知道如何在不传递随机获取参数的情况下强制浏览器重新加载图片。 - arik
1
据我所知,目前没有办法做到这一点。如果浏览器看到图像的src是相同的,它就不会重新加载。最近我研究了一个类似的问题,这几乎是我找到的唯一解决方法。当然,如果有人知道其他选项,我会非常高兴知道! - nico
1
好的,我会等待并保持问题开放。也许有人会找到答案。 - arik

0

你也可以通过Ajax请求获取图像的base64编码,并将其放入img标签中。

当然,我认为这是过度的,而且base64编码的文件大约是原始文件大小的4/3。(一个3kb的图像在base64上大约是4kb)。

编辑: 要使img src属性如下所示

data:image/png;base64,base64编码的图像


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接