Laravel 5.4如何在邮件中嵌入图片

25

我刚刚将我的 laravel 安装程序从 5.2 升级到 5.3,然后再按照官方升级方法升级到 5.4

现在,我正在尝试使用其中一个新功能,即创建一个 markdown 格式的电子邮件。

根据在https://laravel.com/docs/5.4/mail#view-data找到的文档:

要嵌入内联图片,请在电子邮件模板中的 $message 变量上使用 embed 方法。Laravel 会自动使 $message 变量对所有电子邮件模板可用,因此你不必担心手动传递它:

不过,这个:

<img src="{{ $message->embed(public_path().'/img/official_logo.png') }}">

将会产生以下错误:

未定义变量:message

我是不是漏掉了什么?或者在升级指南中有一些未记录的内容?

后续编辑:

我正在使用以下代码调用邮件函数:

\Mail::to($user)->send(new WelcomeCandidate($user, $request->input('password')));

而WelcomeCandidate看起来像这样:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

use App\Models\User;

class WelcomeCandidate extends Mailable
{

    use Queueable, SerializesModels;

    public $user;
    public $password;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct(User $user, $password)
    {
        //
        $this->user = $user;
        $this->password = $password;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        $this->subject('Welcome!');
        return $this->markdown('emails.welcome-candidate');
    }
}

展示更多的代码,但错误信息已经很清楚了。你没有在你的可邮寄类或通知类中定义message变量,或者你没有在你的可邮寄/通知类的构造函数中为它分配任何值。另外,如果你要使用markdown,你不需要使用image标签。 - Christophvh
我按照指示完成了,正如您在引用的文本中所看到的。我应该提供什么代码? - Angelin Calu
执行可发送类的代码:例如: $message = "你好"; Mail::to($request->user())->send(new OrderShipped($message)); - Christophvh
我已经在问题中添加了代码。 - Angelin Calu
这个问题在这里也被提出过:https://github.com/laravel/framework/issues/17629。但是没有解决方案。 - Angelin Calu
9个回答

26

2
已经尝试过了。我得到了一个空的img <img alt="alt here" title="title here" style="font-family:Avenir,Helvetica,sans-serif;box-sizing:border-box;max-width:100%"> - Angelin Calu
你尝试使用{{assets('img/official_log.png')}}了吗?也许问题出在路径上? - Christophvh
路径是问题所在。而且我正在尝试内联方法,这可能是另一个问题。 - Angelin Calu
很高兴能帮到你!是的,目前嵌入方法似乎与Markdown不太兼容。 - Christophvh
1
是的。好吧,最终会做出类似于<td class="logo"><img src="{{asset('img/official-logo.png')}}" alt="alt here"></td>这样的东西,在vews/vendor/mail/html/layout.blade.php中,因为我将把该标志作为默认值放入所有电子邮件中。 - Angelin Calu

15

试一试:

<img src="data:image/png;base64,{{base64_encode(file_get_contents(resource_path('img/email/logo.png')))}}" alt="">
或者
![](data:image/png;base64,{{base64_encode(file_get_contents(resource_path('img/email/logo.png')))}})

我喜欢这个解决方案,但不幸的是没有成功。 - Benco
尽管我喜欢将序列化的图像数据粘贴到图像标签中,但它们在许多电子邮件服务和客户端上是不受欢迎的。我喜欢用base64编码的图像来完成某些目的,不要误会。只是电子邮件并不是专门用于显示图像和实现呈现可见图像的单一目的。现在已经是2018年下半年了,我们将看到这个评论的真实性如何。也许几年后情况会有所改变... - BradChesney79
3
在诸如 Gmail 等服务中,如果 HTML 行过长会被强制换行(大约在 10,240 个字符处);如果您的图像文件大于 8KB,则其 base64 编码字符串中将插入空格,导致无法正常显示该图像 - <img src="data:...r4ScdV3sideY8TdZ..."> - amphetamachine

6
解决了我的问题!
  <img src="{{ $message->embed(base_path() . '/img/logo.png') }}" />
Controller:


\Mail::send(['html' =>'mail'],
        array(
            'name' => $r->name,
            'email' => $r->email,
            'user_message' => $r->message,
           // 'telephone'=>$r->telephone,
           // 'subject'=>$r->subject
        ), function($message) use ($r)  {

            $message->to('abc@gmail.com')->subject('Contact Form || abc.com');
            $message->from($r->email);
            // ->setBody($r->user_message); // assuming text/plain

        });

如果您在本地主机上,可以使用public_path函数代替base_path函数。

5

您也可以使用这个有用的包

https://github.com/eduardokum/laravel-mail-auto-embed

从自述文件中获取:
它的使用非常简单,您可以正常编写Markdown:
@component('mail::message')
# Order Shipped

Your order has been shipped!

@component('mail::button', ['url' => $url])
View Order
@endcomponent

Purchased product:

![product](https://example.com/products/product-1.png)

Thanks,<br>
{{ config('app.name') }}
@endcomponent

发送时,它将替换通常生成的链接:

<img src="https://example.com/products/product-1.png">

通过嵌入的内联图像附件:
<img src="cid:3991f143cf1a86257f8671883736613c@Swift.generated">

3

我遇到了相同的问题并找到了解决方案。

在渲染图像之前,您需要使用以下命令将符号链接从"public/storage"创建到"storage/app/public":

php artisan storage:link

在 "storage/app/public" 目录下,你应该有一个名为 "images" 的文件夹。 现在,你可以在你的 markdown.blade.php 文件中呈现这段代码:

!['alt_tag']({{Storage::url('/images/your_image.png')}})

第二个选项类似:

!['alt_text']({{Storage::url($comment->user->image->path)}}) 

两者都可以正常工作。


0
下面的解决方案适用于我。
<img src="{{ $message->embed(asset('img/logo.png')) }}"/>

.env文件中。
对于本地:APP_URL=http://localhost/project_name 对于生产环境:APP_URL=https://www.example.com 参考:https://laravel.com/docs/7.x/mail#inline-attachments

0

Laravel 在所有版本(7、8、9 和 10)中都支持嵌入方法。 如何在 Laravel 中嵌入图像?

<img src="{{ $message->embed($pathToImage) }}">

Laravel会自动将$message变量提供给所有的电子邮件模板,因此您不需要手动传递它:


0

您可以尝试以下方法:

class WelcomeCandidate extends Mailable
{
    use Queueable, SerializesModels;

    public $message;
    public function __construct(User $user)
    {
        $this->user = $user;
        $this->message = (object) array('image' => '/path/to/file');
    }
}

-1

在后端,我创建了用于显示图像的端点。并将所需的图像放置在resource/img中。Laravel代码如下:

 public function getImage($name)
 {
        return response()->file(base_path() . '/resources/img/' . $name . '.png');
 }

在我的HTML电子邮件模板中,我创建了一个带有背景图片的div。
<div style='background: url("https://mysite1.com/api/v1/get_image/logo")'></div>

对我来说有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接