I'm trying to send nice MIME emails, where html will be displayed whenever possible, and when not possible it should have a textual fallback.
That is, when html contains an image, the "alternative" part should show "img ... should be here".
The problem is that I see everything, also the alternative, in gmail.
Is there something wrong with my MIME message?
Here's the content:
Content-Type: multipart/mixed; boundary="===============9061258228856181354=="
MIME-Version: 1.0
From: [email protected] <[email protected]>
To: [email protected]
--===============9061258228856181354==
Content-Type: multipart/alternative; boundary="===============2889524977048828163=="
MIME-Version: 1.0
--===============2889524977048828163==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
img 1043833786270341319 should be here
--===============2889524977048828163==--
--===============9061258228856181354==
Content-Type: image/jpeg; name="sky.jpg"
MIME-Version: 1.0
Content-ID: <1043833786270341319>
Content-Transfer-Encoding: base64
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsK
CwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQU
FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCAEbAakDASIA
AhEBAxEB/8QAHQAAAgIDAQEBAAAAAAAAAAAAAgQBAwUGBwAICf/EADoQAAEEAQMDAwIFAgYBBAMB
--===============9061258228856181354==
Content-Type: multipart/related; boundary="===============7011550496984103126=="
MIME-Version: 1.0
--===============7011550496984103126==
Content-Type: text/html; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
<div><h1>bla</h1></div><img src="cid:1043833786270341319" title="1043833786270341319"/>
--===============7011550496984103126==--
--===============9061258228856181354==--
Notes: The image code was cut just so its not huge code. Again, simply the goal is to show a fallback for non-html readers, which should have a different message than the html message. A capable mailer should NOT show the alternative message, right?
Basically, your mail is not arraged correctly. There are a few ways to arrange the parts in a MIME message so that they make sense to a mail agent. Let's start from the simple and go through to the complicated option:
The simplest of all is text with a few attachments. For example, you want to send your CV to someone, So you write a few words of introduction and attach one or more document (cover letter, CV):
Multipart/mixed means that the e-mail agent will show the parts serially - one after the other.
inline
, and the e-mail agent is capable to show the given attachment type, then it will be shown inside the message itself - at its end.attachment
, they will usually be shown as some sort of icons or links for saving the attachments.If you want to send a pretty HTML message, it is customary to include both a plaintext version and an HTML version. This is so that the recipient may be able to read it even in an e-mail reader that doesn't support HTML. You need to use multipart/alternative:
So, again, the message content includes three parts, the body and the two attachments. But the body itself is a
multipart/alternative
, and it contains the plaintext version and the HTML version. Remember to put the plaintext first, and the HTML second, as the convention is for the mail agent to pick the last alternative that it knows how to display.The attachments are going to be displayed serially after the body, just like before, because they are the next parts in the main level, which is
multipart/mixed
.Now let's look at a mail that doesn't have "attachments", but it does have images that are supposed to be embedded inside the HTML. In this case, the mail agent needs to know that the attachments are not just files sent over to the reader to be downloaded, but that it should display them in association with the HTML. So the correct mime type for that is
multipart/related
, to show that the parts are related. In this case, you also need to give them proper content IDs, and use those content IDs in the HTML. This is not part of the MIME standard, but it's how HTML mail is usually done these days.As far as MIME is concerned, such a message will look like:
This time we don't have attachments, so we can put the multipart/alternative as our top level content. It has the plaintext alternative first, like before, but the second alternative is itself a
MimeMultipart("related")
.Inside it, you have the HTML part, and the two images. The HTML and its images must always be parts of the same multipart/related object.
Now, what if you wanted to attach your document to such a message, one that has HTML and images inside it? Then you would be using something like this:
So your top level object is multipart/mixed, allowing you to add attachments serially to your message. The message "body" (the first part of the
multipart/mixed
) is the complex structure ofmultipart/alternative
with an embeddedmultipart/related
. And then the other attachments follow that.In summary:
multipart/mixed
message has a first part which is supposed to be your readable message, and the rest are attachments. All parts will be shown by the reader's mail agent.multipart/alternative
message gives different display alternatives of the same content, ordered from most common denominator to most rare presentation type (e.g. plain text→HTML→rich text→proprietary formatting) and the recipient's mail program picks the last one that it knows how to display. You see only one of the alternatives.multipart/related
message is usually used to combine an HTML body with its inline messages. The first part is the HTML, the other parts have Content-IDs that the HTML uses for its<img src="..." />
tags.Now let's look at your own hierarchy, based on the boundary strings. Your outermost level is a
multipart/mixed
with the boundary===============9061258228856181354==
. If you look for all the places that this border appears, you'll see that there are three parts to thismultipart/alternative
.The first part is:
This part is a
multipart/alternative
, but it only has one alternative part - whose content type is text/plain.The second part is:
So it's an image.
The third part is:
Well, it's a
multipart/related
. But it only has one part - thetext/html
message. The image is not part of it.So instead of having the following hierarchy, which is the appropriate one for what you described (text plain and html alternatives, the html part having an embedded image)
You have this wrong hierarchy:
Because all the parts are in a
multipart/mixed
, they are displayed serially, not as alternatives. Because thetext/plain
and themultipart/related
are not parts of the samemultipart/alternative
, the mail agent is not aware that they are alternatives to each other. It sees no other alternative to thetext/plain
, there is only one part in thatmultipart/alternative
.Because the
multipart/related
part does not contain the images, there will be mail agents which will fail to put the image inside the HTML properly. Also, because of this, the image is probably shown to you serially or as an attachment - it stands alone and not related to anything else.So you have to rearrange your message to conform to the proper hierarchy for the alternatives to work and for the image to be properly related to the HTML.