0

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!

enter image description here

2 Answers 2

1

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> 
Sign up to request clarification or add additional context in comments.

1 Comment

This is perfect thanks a lots. just one question! is there any way to get directly the image by Ajax? instead of encoding the image in PHP?
1

Looks like there is a slight disconnect between what you return from the ajax call and what you try to display.

This sends out the jpeg in its natural binary form.

header("Content-type: image/jpeg"); imagejpeg($target_layer); 

Here you treat it like an base64_encoded image.

$("#captcha").attr("src", 'data:image/jpeg;base64,'+data); 

At that point you might want to do an actual base64_encode() and send that back or encode it on the JS side.

For example

$("#captcha").attr("src", 'data:image/jpeg;base64,'+btoa(data)); 

3 Comments

Thanks for reply but the result is same! still unknown source
I assume your captcha is pre-defined as <img id="captcha" src="" />?
Correct, it is like that

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.