Skip to content

Instantly share code, notes, and snippets.

@JonathonRichardson
Created March 14, 2018 16:57
Show Gist options
  • Save JonathonRichardson/bf27f884028be4fa2525d97836e9c349 to your computer and use it in GitHub Desktop.
Save JonathonRichardson/bf27f884028be4fa2525d97836e9c349 to your computer and use it in GitHub Desktop.
File Download Helper Functions
/**
* Takes a HTTP response that represents file data and parses out the file name from
* the Content-Disposition and pulls the Blob object representing the body content of
* the response.
* @param response The response object that fetch returns
*/
export function getBlobAndFilenameFromResponse(response: Response): Promise<{filename: string, blob: Blob}> {
// Get the file name
let filename = 'unknown';
let contentDispositionRaw = response.headers.get('Content-Disposition');
if (contentDispositionRaw !== null) {
let contentDisposition = parseContentDisposition(contentDispositionRaw);
if (contentDisposition !== null && contentDisposition.filename) {
filename = contentDisposition.filename;
}
}
return response.blob().then(blob => {
return { filename, blob };
});
}
/**
* Represents the contents of the Content-Disposition response header.
*/
export interface IContentDisposition {
value: string;
name?: string;
filename?: string;
}
const keyWithQuotedValueRegex = /^\s?([^=]+)\s?=\s?(([^"]+)|"([^"]+)"|\'([^\']+)\')\s?/;
/**
* Parses the values of the Content-Disposition header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
*
* TODO: Support the filename* syntax.
*
* @param contentDisposition The value of the Content-Disposition header
*/
export function parseContentDisposition(contentDisposition: string): IContentDisposition | null {
let parts = contentDisposition.split(';').map(piece => {
// Remove excess whitespace
piece = piece.trim();
return piece;
});
let firstPart = parts.shift();
if (firstPart == null) {
return null;
}
else {
let response: IContentDisposition = {
value: firstPart
};
parts.forEach(part => {
let match = keyWithQuotedValueRegex.exec(part);
if (match != null) {
let key = match[1];
let value = match[2];
// The value might be a quoted string, so using JSON.parse()
// will remove the quotes and properly unescape the insides.
value = value.startsWith("'") || value.startsWith('"') ? JSON.parse(value).toString(): value;
if (key === 'name') {
response.name = value;
}
else if (key === 'filename') {
response.filename = value;
}
}
})
return response;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment