通过 jQuery Ajax 调用获取 PHP 生成图像的问题

Issue on Getting PHP Generated Image By jQuery Ajax Call

能否请您看一下这段代码,让我知道为什么我无法通过 jQuery 中的 Ajax 调用获得 PHP 生成的验证码(图像)?

我的captcha.php就是这个

<?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);
?>

这是我的 jQuery Ajax 请求

$(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);
    });
});

在我的控制台上出现此错误

Request failed: parsererror

并且在源代码中 #captcha 的 src 显示未知!

看起来您从 ajax 调用中 return 的内容与您尝试显示的内容之间存在轻微的脱节。

这将以其自然二进制形式发送 jpeg。

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

这里你把它当作 base64_encoded 图片。

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

那时你可能想做一个实际的 base64_encode() 并将其发回或在 JS 端对其进行编码。

例如

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

PHP 脚本正在发送图像 headers 而不是您期望的 base64 编码数据,因此请尝试:

<?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 ) );
?>

然后稍微修改 ajax 以删除预期的数据类型

<!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>

无需在 PHP 中进行编码即可完成相同的操作(根据您在下面评论中提出的问题)- 是的,可以做到。以下省略了 jQuery 代码,因为我不使用 jQuery 并且不知道要使用的方法,所以一些非常简单的香草 javascript 和你原来的 PHP 代码将工作。

<?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 ) );
?>

客户端:

<!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>