43 lines
1.3 KiB
JavaScript
43 lines
1.3 KiB
JavaScript
|
|
async function inferSource(src){
|
|
let response = await fetch(src, {
|
|
method: 'HEAD'
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
|
|
// 1. Get the Content-Disposition header value
|
|
let contentDisposition = response.headers.get('Content-Disposition');
|
|
|
|
// 2. Process the value to extract the filename
|
|
let file = extractFilename(contentDisposition)
|
|
let srcParts = src.split("/")
|
|
srcParts.pop()
|
|
srcParts.push(file)
|
|
return srcParts.join("/")
|
|
}
|
|
|
|
function extractFilename(contentDispositionHeader) {
|
|
if( !contentDispositionHeader ) return ""
|
|
// Check for the preferred 'filename*' (UTF-8 encoded)
|
|
// This looks for 'filename*=' followed by the encoding and the filename
|
|
const utf8Match = contentDispositionHeader.match(/filename\*=(?:utf-8|UTF-8)''(.+?)(?:;|$)/i);
|
|
if (utf8Match && utf8Match[1]) {
|
|
// The filename might be URL-encoded, so decode it
|
|
// The value in your example is 'website.jpg' which is not encoded,
|
|
// but a proper implementation should decode.
|
|
return decodeURIComponent(utf8Match[1].trim());
|
|
}
|
|
|
|
// Fallback to the simpler 'filename'
|
|
const basicMatch = contentDispositionHeader.match(/filename="(.+?)"/i);
|
|
if (basicMatch && basicMatch[1]) {
|
|
return basicMatch[1].trim();
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
export { inferSource };
|