You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel Blade模板中嵌入含Blade代码的变量?

Laravel邮件内嵌动态图片问题解决办法

为啥你之前的方法不行?

  1. Blade模板不会解析{!! $details['body'] !!}输出的变量里的Blade语法——你把{{ $message->embed() }}塞到变量里,模板只会把它当普通文本输出,根本不会执行这段代码生成图片CID。
  2. 很多邮件客户端对base64内嵌图片的支持很差,直接用base64大概率显示不出来。

靠谱的解决方案

方案1:用占位符提前替换图片(最推荐)

这个方法安全又兼容,步骤如下:

  1. 前端提交内容时,别写Blade代码,给图片位置加个占位符,比如写成[IMAGE:这里填base64字符串]。
  2. 在发送邮件的逻辑里,解析占位符,把base64转成内嵌附件:
// 假设你在邮件类的build方法里
public function build()
{
    $body = $this->details['body'];
    // 匹配所有图片占位符
    preg_match_all('/\[IMAGE:(.*?)\]/', $body, $matches);

    foreach ($matches[1] as $index => $base64Content) {
        // 解码base64
        $imageData = base64_decode($base64Content);
        // 生成唯一文件名(根据实际图片类型改后缀)
        $fileName = 'email_img_' . $index . '.png';
        // 嵌入图片拿到CID地址
        $cid = $this->message->embedData($imageData, $fileName, 'image/png');
        // 把占位符换成带CID的img标签
        $body = str_replace($matches[0][$index], "<img src='cid:$cid' />", $body);
    }

    return $this->view('emails.your_template')->with('body', $body);
}
  1. 最后在Blade模板里直接输出处理好的内容:
{!! $body !!}

方案2:手动编译变量里的Blade代码(谨慎用)

如果你非要在变量里写Blade语法,可以手动编译,但一定要做好内容过滤,防止XSS攻击:

// 还是在邮件类的build方法里
use Illuminate\View\Compilers\BladeCompiler;
use Illuminate\Filesystem\Filesystem;

public function build()
{
    $compiler = new BladeCompiler(new Filesystem(), storage_path('framework/views'));
    // 编译变量里的Blade代码
    $compiledStr = $compiler->compileString($this->details['body']);
    // 渲染编译后的内容,把$message传进去
    $renderedBody = view()->makeFromString($compiledStr, ['message' => $this->message])->render();

    return $this->view('emails.your_template')->with('body', $renderedBody);
}

模板里同样用{!! $body !!}输出,这个方法只适合你能完全控制输入内容的场景,别用来处理用户随便提交的内容。

方案3:存到公开目录用绝对URL

之前存storage没生效?可能是没建软链接:

  1. 先跑命令创建storage到public的软链接:
php artisan storage:link
  1. 把base64图片存到storage/app/public/images:
$imageData = base64_decode($base64String);
$filePath = 'images/' . uniqid() . '.png';
Storage::disk('public')->put($filePath, $imageData);
// 获取可访问的绝对URL
$imageUrl = asset('storage/' . $filePath);
  1. 把$details['body']里的base64图片替换成<img src="$imageUrl" />再输出到模板就行。

总结

优先用方案1,兼容所有邮件客户端,还安全。方案2尽量别碰,方案3适合图片需要长期保存的场景。

内容的提问来源于stack exchange,提问作者pdh28907

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 02:20:17