今天在使用一个验证码图片生成方法时,发现生成的 base64 字符串无法展示图片:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
</head>
<body>
    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAAAoCAIAAACjL4WRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAM\r\nS0lEQVR4nO2beVSTVxrGn2wEyAKyhj0gi1oEiwZKRwSX2tZal1FH7aJOnZaOVUerdeuida1KW62t\r\nrXWNrR3RcalVZ4YehMG9CMpuVJYqkhBAQkJIINv88dGPjwAhCah4js9fN2/uvdyc33nee+/7fdD+\r\n13AaT9W3RX/cC3iq7vUU0hOgp5AeqQ6LUg6LUmwdxXwYS+m5ZoVJDt6OeNyr6B1RqczIXmrHDH0R\r\n0hNBqP6mRn5ZrdcYWTyGbxKPG+BA/bbnYKjqi5AAGA0GAHQGo3envZcuVdxSCcf78QI4dk/y+2lF\r\n7jqpQqKlBoNedZHfPE5+7DkYqvoWJE2DInlY9cSJX+1/sxImk5OLa8Czw4ZMns7

此处省略一大段...

33o\r\nvyqeqis9/Z/ZJ0D/B9liXpvUr2jqAAAAAElFTkSuQmCC\r\n">
</body>
</html>

原来是RFC2045中有规定:

The encoded output stream must be represented in lines of no more than
76 characters each.

Base64一行不能超过76字符,超过则添加回车换行符。

于是增加一个替换掉 \r\n 的方法,问题解决。

原代码:

ob_start();
imagepng($img);
$content = ob_get_contents();
ob_end_clean();
imagedestroy($img);
        
$b64Img = 'data:image/png;base64,' . chunk_split(base64_encode($content));

新代码:

$b64Img = 'data:image/png;base64,' . str_replace("\r\n", '', chunk_split(base64_encode($content)));

需要注意的是,替换 \r\n 需要使用双引号,单引号会导致替换不生效的问题。

原因就是 \r\n 是换行符,不是普通的字符,所以需要使用双引号解决。

标签: php, base64