Rails 如何让邮件的内容为动态生成且是 HTML 格式?

felixding · 2013年06月07日 · 最后由 _samqiu 回复于 2013年06月13日 · 6974 次阅读

我想让邮件中的正文全部由变量传递进来,并且在邮件发出去时,能够保留变量的 HTML 格式。

邮件模板是这样的(部分):

<body>
  <%= @body.html_safe %>
</body>

现在的问题是在发出来的邮件的正文中,HTML 部分都直接显示出来了,而没有被解析。就像这样:

<p>如果你愿意参与试用,请知晓并遵守以下事项:</p>

请问此问题该如何解决?

看起来像是把 HTML 格式的邮件当作文本格式发出去了。

http://api.rubyonrails.org/classes/ActionMailer/Base.html

The mail method, if not passed a block, will inspect your views and send all the views with the same name as the method, so the above action would send the welcome.text.erb view file as well as the welcome.text.html.erb view file in a multipart/alternative email.

所以修改一些邮件模板的后缀名,改成 finename.text.html.erb 试试看。

这个模板是用什么后缀名的?

谢谢 Daniel,补充一些信息: 1.模板的确是.html.erb 格式的; 2.body 标签里面还有一些其它的 HTML 标签,并且引入了 partial,这两部分的 HTML 都被正确的处理了; 3.只有这个@body变量不行。

这里是这个模板 body 部分的代码:

<body>
  <%= @body.html_safe %>

  <%= render "user_mailer/sender" %>

  <%= render partial: "user_mailer/unsubscribe", locals: {user: @user, notification_type: @notification} %>
</body>

<%= sanitize @body >% 看看,html_safe 和 raw 都可能是个安全漏洞,不要用。

要看一下这个 @body 是怎么生成的,我怀疑这个变量已经是 HTML Escape 过了的,所以即使用了 html_safe 对其没有影响。

能看一下@body怎么生成的么?

@body是从 emails_controller 的表单中提交上来的。

提交上来后,我会把它记录到数据库里,然后生成邮件并发出去。

我刚才看了一下数据库中的记录,看起来没问题:

e.body
=> "<p>你好,我们邀请你首先试用

@felixding 没遇到过……分析不出来

大概找到原因了。如果用 delayed_job 发邮件,内容就会被过滤,直接发就没问题。

#9 楼 @felixding 蛮神奇的问题。

BTW, kick dj w/ sidekiq.

感谢各位,问题已解决!

做法是不要给 dj 传递要发送的@body变量,而是把整个email对象都丢给它,这样它就不会过滤 HTML 了。

原来是:

UserMailer.delay(run_at: interval.seconds.from_now).dm(r, self.title, self.body)

现在是:

UserMailer.delay(run_at: interval.seconds.from_now).dm(r, self)

#11 楼 @felixding 其实应该传数据库 ID,这样储存空间占用更小,也避免反序列化出现问题。

我怎么觉得raw就可以了呢……

#12 楼 @Rei @felixding

  • 1,建议直接传 ID
需要 登录 后方可回复, 如果你还没有账号请 注册新账号