mirror of
https://github.com/saltbo/zpan.git
synced 2026-08-29 00:01:42 +08:00
fa136a5112
Uploading a file with a non-ASCII name (Chinese, emoji, …) failed with "Failed to execute 'setRequestHeader' on 'XMLHttpRequest': String contains non ISO-8859-1 code point." The presigned PUT's signed Content-Disposition put the raw filename in the plain `filename="..."` parameter, which the browser then rejects when setting it as an XHR request header. Add a shared attachmentContentDisposition() helper that keeps `filename=` ASCII-only and carries the real name in `filename*=UTF-8''`, and route all three construction sites through it so the signed and client-returned values stay identical (the value is part of the SigV4 signature). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
13 lines
751 B
TypeScript
13 lines
751 B
TypeScript
// Builds an RFC 6266 `Content-Disposition` for forced downloads.
|
|
//
|
|
// The plain `filename=` parameter must be ASCII-only: it is signed into the S3
|
|
// presigned PUT and then set as an XHR request header by the browser, and
|
|
// `XMLHttpRequest.setRequestHeader` rejects any value containing a code point
|
|
// above U+00FF ("String contains non ISO-8859-1 code point"). Non-ASCII names
|
|
// (Chinese, emoji, …) are carried losslessly by the percent-encoded
|
|
// `filename*=UTF-8''` form, which every modern browser prefers.
|
|
export function attachmentContentDisposition(name: string): string {
|
|
const asciiFallback = name.replace(/[^\x20-\x7e]|["\\]/g, '_')
|
|
return `attachment; filename="${asciiFallback}"; filename*=UTF-8''${encodeURIComponent(name)}`
|
|
}
|