Send string to php gd through ajax request
Asked Answered
E

5

7

I try to create a captcha code image with php gd :

$im = imagecreatetruecolor(100, 25);
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im, 0, 0, 0);
imagefilledrectangle($im, 0, 0, 399, 29, $white);
$imgstring=$_GET['captcha'];
$font = 'RAVIE.TTF';
imagettftext($im, 15, 0, 10, 20, $black, $font, $imgstring);
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);

The GET value is send with ajax like this:

var randstring;
function Captcha() {
    randstring = Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, 5))).toString(36).slice(1);

            $.ajax({
                url: 'test_image.php',
                data: {'captcha' : randstring},
                method: 'GET',
                success: function (data){
                    console.log(data);
                },
                error: function (){
                    alert('Error');
                    return false;
                }   

            });
        }

HTML:

<img src="test_image.php">

Though it gives no errors , the image is not generated . Yes, the request reach the php script , i already checked , but something blocks image from being generated...

UPDATE Actually the image is generated, and also the ajax request is sent. But on the test_image.php script , $_GET['captcha'] ( the request ) is not recognized so it will just output a blank string in that image , though the image is there , but without a string .

Ezar answered 8/10, 2015 at 17:22 Comment(11)
so if you load test_image.php directly you can see the image there?Retrospect
the $_GET string is not recognized , so the image has no string , but it exist on the page , and the ajax request is also sent , if instead of $_GET['captcha'] i put a random static string , the image will have that stringEzar
Have you tried to skip ajax by trying something like : <img src="test_image.php?captcha=randomnr">. If it works you can still update randomnr with a random value from js.Retrospect
ah i see now your update...Retrospect
what's the point of the captcha then ? if i just put the string in url , where every bot can simply copy+paste itEzar
to be fair whatever you generate with javascript is clearly available to everybody.. sending it via ajax won't hide your generated code ;) By the way i was just wondering if it works in that way. Can you see the image + code if you surf directly to URL/test_image.php?captcha=randomnr ?Retrospect
to explain better my previous comment: ie: if you want to hide the captcha code you should generate it with php when you load the form page and save it in a session variable. After the form is submitted you compare the code that was inserted with what you have in your session.Retrospect
yes it works like this ... it may be something wrong with my ajax request... but i can't figure out...Ezar
@Retrospect , i know but i have my own reasons for using js , though i know the danger i expose toEzar
Maybe font problems?Alkmaar
@Alkmaar , no .. that's for sureEzar
S
4

You want to load the content of your image using AJAX but do not want to put URL in img tag for security reason. So, in that case, you should fetch base64 encoded data of the image and use it inside your img src.

Use following code for your php file:

<?php

// Start output buffering
ob_start();
$im = imagecreatetruecolor(100, 25);
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im, 0, 0, 0);
imagefilledrectangle($im, 0, 0, 399, 29, $white);
$imgstring=$_GET['captcha'];
$font = 'RAVIE.TTF';
imagettftext($im, 15, 0, 10, 20, $black, $font, $imgstring);
imagepng($im);
imagedestroy($im);

// Get Image content a variable
$captchaImageData=ob_get_contents();
// Clean the output buffer
ob_end_clean();

//Base64 Encode
$encodedData = base64_encode($captchaImageData);

echo $encodedData;
?>

You Javascript code will be following:

function Captcha() {
    var randstring = Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, 5))).toString(36).slice(1);

    $.ajax({
        url: 'test_image.php',
        data: {'captcha' : randstring},
        method: 'GET',
        beforeSend: function(data) {
            $('captchaImage').attr('src','laoding.gif');
        },
        success: function (data){
            // data is base64_encoded data of your image
            // load it in your img suorce
            $('captchaImage').attr('src','data:image/png;base64,'+data);
        },
        error: function (){
            alert('Error');
            $('captchaImage').attr('src','error.jpg');
        }   

    });
}

You HTML element will be updated with an ID. Also put some sort of loading gif/animation until image is loaded.

<img src="loading.gif" id="captchaImage">

Now calling Captcha() funciton in javascript will always load a new captcha image. Put appropriate loading.gif and error.jpg images

Sialoid answered 20/10, 2015 at 11:38 Comment(0)
R
0

Can you try this in your js code? Instead of loading the image via ajax we can try just to append the code to the src value of the image:

randstring = Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, 5))).toString(36).slice(1);

$("#image").attr('src',$("#image").attr('src') + "?captcha="+randstring );

HTML

<img id="image" src="test_image.php">
Retrospect answered 13/10, 2015 at 13:38 Comment(5)
i can tell you by now that is working , but is not what i 'm looking for ... if i'll send it with ajax, it won't be so easy to access it , especially for spam botsEzar
@PetruLebada ok i ll update the answer then.. by they way your code can be either safe on the js side or not safe: fixing the ajax request won't be making it any safer since with both solutions the randstring variable still contains your code.Retrospect
can you give me some examples on how can my captcha code can be accessed ?Ezar
@PetruLebada the point here is that both solutions are safe enough from bots since they are made to scan the page and submit data usually for the most used protection systems. Since your solution was made ad hoc for your site unless someone creates a bot on purpose to attack it, it should be safe enough. I don't know now if bots go around checking also js variables to discover a captcha code but i doubt it.Retrospect
And even if they can somehow read your code in my experience having a couple hidden input fields (which aren't supposed to be submitted) are usually enough to block any bot that might find a way to force your captcha code.Retrospect
D
0

try to replace the get param with a test variable: $imgstring='this is some text';

Does this show an image with the text.

btw. this is not a very good way for a captcha, all bots could easily read the ajax request. Would be better to generate the captcha by the test_image.php file and store the random string in session for example.

UPDATE

So if you really want to use ajax you can´t do it the way you do. You need to use base64 encode to show the picure via ajax. javascript:

$.ajax({
url: 'test_image.php',
data: {'captcha' : randstring},
method: 'GET',
success: function (data){
console.log(data);
$('#mycaptcha').attr('src','data:image/png;base64,'+data);
},error: function (){alert('Error');return false;}   
});

....

Captcha();

PHP:

imagettftext($im, 15, 0, 10, 20, $black, $font, $imgstring);
ob_start();
imagepng($im);
$imgdata=ob_get_contents();
ob_end_clean();
imagedestroy($im);
echo base64_encode($imgdata);

html: [img id="mycaptcha"]

cant post html brackets .. use <>

Disjuncture answered 13/10, 2015 at 13:39 Comment(1)
yes like this is working , and yes i know with php is safer , but i need to use js , and i don't know if spam bots can access the ajax request ...Ezar
L
0

You write:

<img src="test_image.php" id="img">

but do not passing any parameters there. Of course your PHP script does not see any $_GET['captcha']. Your AJAX is being called but does not affectes to img due to is not relaed to it.

Try:

var c = Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, 5))).toString(36).slice(1);
$("#img").attr("src", "test_image.php?captcha=" + c);

This will send your string in GET query.

If you want to call it on some button click ("Refresh captcha" for example), call this code on its onclick event.

Lunch answered 18/10, 2015 at 11:5 Comment(0)
C
0

Check your server log. Maybe imagettftext cannot open the specified font file.

Try to copy the font file to the same directory as the php script.

Then:

putenv('GDFONTPATH=' . realpath('.'));
$im = imagecreatetruecolor(100, 25);
$white = imagecolorallocate($im, 255, 255, 0);
$black = imagecolorallocate($im, 0, 0, 0);
imagefilledrectangle($im, 0, 0, 399, 29, $white);
$imgstring=$_GET['captcha'];
$font = 'RAVIE.TTF';
imagettftext($im, 15, 0, 10, 20, $black, $font, $imgstring);
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
exit;
Castellatus answered 20/10, 2015 at 11:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.