If you are not dealing with multipart body data, then this function comes in handy. It fetches the filename from the Content-Disposition header value (format: inline; filename=demo3.png) and decodes it as necessary.
const extractFileNameFromContentDisposition = disposition => {
if (disposition
&& (disposition.startsWith('attachment') || disposition.startsWith('inline'))
) {
let filename = disposition.startsWith('attachment')
? disposition.replace("attachment;", "")
: disposition.replace("inline;", ""); // replaces only first match
filename = filename.trim();
if (filename.includes("filename*=") && filename.includes("filename=")) {
let filenames = filename.split(";"); // can parse by ";" because all ";"s inside filename are escaped
if (filenames.length > 1) { // "filename=" or "filename*=" not found inside filename
if (filenames[0].trim().startsWith("filename*=")) { // prefer "filename*="
filename = filenames[0].trim();
} else {
filename = filenames[1].trim();
}
}
}
if (filename.startsWith("filename*=")) {
filename = filename.replace("filename*=", "")
.split("''").slice(1).join("''"); // remove encoding and ''
filename = decodeURIComponent(filename);
} else if (filename.startsWith("filename=")) {
filename = filename.replace("filename=", "")
if (filename.startsWith('"') && filename.endsWith('"')) {
filename = filename.slice(1, filename.length - 1); // remove quotes
}
}
return filename;
}
}
The outcome of this function can be divided into name and extension like so:
let fullName = extractFileNameFromContentDisposition("inline; filename=demo.3.png").split(".");
let fileExtension = fullName[fullName.length - 1];
fullName = fullName.slice(0, fullName.length - 1).join(".");
console.log(fullName); // demo.3
console.log(fileExtension); // png
You can generate a thumbnail using SVG, for instance:
let colorPalette = {"png": "red", "jpg": "orange"};
// this is a basic example; feel free to create something more appealing
let createSVGThumbnail = extension => `<svg xmlns="http://www.w3.org/2000/svg" width="18" height="20" viewBox="0 0 18 20">
<rect x="0" y="0" width="18" height="20" fill = "#FAFEFF"/>
<rect x="0" y="7" width="18" height="6" stroke="${colorPalette[extension] || "blue"}" fill = "${colorPalette[extension] || "blue"}"/>
<text stroke = "white" fill = "white" font-size = "6" x = "0" y = "12.5" textLength = "18">${extension.toUpperCase()}</text>
</svg>`;
...
// Utilize it as background-image for HTML element
let backgroundImage = "data:image/svg+xml;base64," + btoa(new TextDecoder().decode(createSVGThumbnail("png")));