Can you please take a look at this code and let me know why I am not able to get a PHP generated captcha (image) by Ajax call in jQuery?
What I have in captcha.php
is simply this
<?php session_start(); $random_alpha = md5(rand()); $captcha_code = substr($random_alpha, 0, 6); $_SESSION["captcha_code"] = $captcha_code; $target_layer = imagecreatetruecolor(70,30); $captcha_background = imagecolorallocate($target_layer, 255, 160, 119); imagefill($target_layer,0,0,$captcha_background); $captcha_text_color = imagecolorallocate($target_layer, 0, 0, 0); imagestring($target_layer, 5, 5, 5, $captcha_code, $captcha_text_color); header("Content-type: image/jpeg"); imagejpeg($target_layer); ?>
and this is my jQuery Ajax request
$(function() { var getCaptcha = $.ajax({ type: "GET", url: 'captcha.php', cache: false, dataType: 'image/jpeg', success: function (data) { $("#captcha").attr("src", 'data:image/jpeg;base64,'+data); } }); getCaptcha.fail(function (jqXHR, textStatus) { console.log("Request failed: " + textStatus); }); });
on my console I am getting this error
Request failed: parsererror
and in source code the src of #captcha
is showing unknown!
Advertisement
Answer
The PHP script is sending image headers not the base64 encoded data that you are expecting so try:
<?php session_start(); $random_alpha = md5(rand()); $captcha_code = substr($random_alpha, 0, 6); $_SESSION["captcha_code"] = $captcha_code; $target_layer = imagecreatetruecolor(70,30); $captcha_background = imagecolorallocate($target_layer, 255, 160, 119); imagefill($target_layer,0,0,$captcha_background); $captcha_text_color = imagecolorallocate($target_layer, 0, 0, 0); imagestring( $target_layer, 5, 5, 5, $captcha_code, $captcha_text_color); # create a temp file to save the image $tmp=tempnam( sys_get_temp_dir(), 'captcha' ); # save the image & then read it's contents imagejpeg( $target_layer, $tmp ); $data=file_get_contents( $tmp ); # clean up imagedestroy( $target_layer ); unlink( $tmp ); # send the base 64 data string exit( base64_encode( $data ) ); ?>
And then modify the ajax slightly to remove the expected dataType
<!DOCTYPE html> <html lang='en'> <head> <meta charset='utf-8' /> <title></title> <script src='//code.jquery.com/jquery-latest.js'></script> <script> $(function() { var getCaptcha = $.ajax({ type: "GET", url: 'captcha.php', cache: false, success: function (data) { $("#captcha").attr("src", 'data:image/jpeg;base64, ' + data ); } }); getCaptcha.fail(function (jqXHR, textStatus) { console.log("Request failed: " + textStatus); }); }); </script> </head> <body> <img id='captcha' /> </body> </html>
To accomplish the same without encoding in PHP ( as per your question in the comment below ) – Yes, it can be done. The following omits the jQuery code as I do not use jQuery and wouldn’t know the methods to use so instead some very simple vanilla javascript and your original PHP code will work.
<?php session_start(); $random_alpha = md5(rand()); $captcha_code = substr($random_alpha, 0, 6); $_SESSION["captcha_code"] = $captcha_code; $target_layer = imagecreatetruecolor(70,30); $captcha_background = imagecolorallocate($target_layer, 255, 160, 119); imagefill( $target_layer,0,0,$captcha_background ); $captcha_text_color = imagecolorallocate($target_layer, 0, 0, 0); imagestring( $target_layer, 5, 5, 5, $captcha_code, $captcha_text_color); header("Content-type: image/jpeg"); exit( imagejpeg( $target_layer ) ); ?>
And the clientside:
<!DOCTYPE html> <html lang='en'> <head> <meta charset='utf-8' /> <title></title> <script> fetch('captcha.php') .then( r=>r.blob() ) .then( data=>{ document.getElementById('captcha').src=URL.createObjectURL( data ); }) </script> </head> <body> <img id='captcha' /> </body> </html>