Multipurpose Internet Mail Extensions (MIME) was originally created for email, as its name suggests.
It used to be, back in the day when cavemen were painting their hands on cave walls, that all email was ASCII text and that was all. If you wanted to include an image, you had to draw it in ASCII-art.
So in order to pass other kinds of data in email, MIME was invented. It allowed emails to contain multiple parts, and had a way of identifying the type of data that was contained within each part.
MIME is still used for email to this day.
But the designers of the web recognized that many of the same problems could be solved by using MIME with the web, as well.
One of the problems is identifying the type of data that is arriving from the server.
Bytes are just numbers. So when the web browser receives a stream of bytes from the server, how can it tell if this is unicode HTML data, binary animated-gif data, or a JPEG vacation photograph? They're all just streams of numbers!
The server has to tell the browser what type this data is. And it does this by specifying the MIME type.
Here are some common MIME types:
- JPEG:
image/jpeg
- GIF:
image/gif
- PNG:
image/png
- JavaScript:
application/javascript
- JSON:
application/json
- CSS:
text/css
- HTML:
text/html
- Plain TXT:
text/plain
- Non-descript data:
application/octet-stream
Octet is another name for an 8-bit value, commonly known as a byte. (Historically the number of bits in a byte varied, even though today they're vitually always 8 bits. An octet is always 8 bits by definition.)
There are a lot of MIME types.
If you have a programmatic endpoint (e.g. an endpoint that generates the data instead of reading it from disk) then you simply specify the type of the data you're sending back.
For example, if you return data is:
{
"animal_type": "goat",
"count": 37
}
then you'll use the content type of application/json
.
But what if you're reading data from a file and serving it?
If the client requests http://example.com/foo.png
, we need to reply with a
type of image/png
. The usual way to do this is to simply map between the file
extension .png
and its MIME type image/png
.
-
Isolate the file extension.
Examples:
File is
frotz.jpg
, extension is.jpg
.File is
foo.bar.txt
, extension is.txt
. -
Map the extension to its MIME type.
Example:
.txt
maps totext/plain
-
If you can't find a mapping for an extension, use
application/octet-stream
.
Comparisons are case-insensitive. Here are some examples:
.jpg
or.jpeg
:image/jpeg
.gif
:image/gif
.png
:image/png
.js
:application/javascript
.json
:application/json
.css
:text/css
.htm
or.html
:text/html
.txt
:text/plain
.ico
:image/x-icon
It comes back in the HTTP header in the Content-Type
field:
Content-Type: text/html
Whichever library you are using should have a way to set the Content-Type
header.
Webservers construct their own HTTP headers so the Content-Type
is included at
that time.
The browser uses the MIME type of the data to decide what to do with it. If it's
text/html
, it displays it. Probably the same with image/*
data. Also
text/plain
.
The browser can display a number of types of data natively. But what if it gets one it doesn't know? There are, after all, about 1.2 zillion MIME types.
In that case, it has two options:
-
It can spawn an external viewer to show the file, if it is aware of one.
-
It can simply download the file and let the user deal with it later.