Created
March 14, 2018 16:57
-
-
Save JonathonRichardson/bf27f884028be4fa2525d97836e9c349 to your computer and use it in GitHub Desktop.
File Download Helper Functions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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