浏览器会根据多个输入决定显示响应、下载响应,还是将其交给
external application from several inputs. Content-Disposition provides a
strong preference, but content type, navigation context, sandboxing, browser
capabilities, and user settings also affect the result.
inline 与 attachment 处置方式 #
attachment 响应请求下载:
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="guide.pdf"
Content-Length: 110352
X-Content-Type-Options: nosniffinline 响应允许在浏览器内呈现:
Content-Type: application/pdf
Content-Disposition: inline; filename="guide.pdf"inline 不保证显示。 The browser needs a viewer for the media
type, and the user can configure some types to download instead. Omitting the
header leaves the choice primarily to the media type and navigation context.
提供安全文件名 #
filename 携带兼容 ASCII 的备用名称。 filename* uses the extended
parameter encoding defined by RFC 8187, which supersedes RFC 5987, and can
represent Unicode:
Content-Disposition: attachment;
filename="report.pdf";
filename*=UTF-8''r%C3%A9sum%C3%A9.pdf应发送两个参数,因为旧客户端可能忽略 filename*;当两者都有效时,符合规范的接收方优先使用 filename*。 Treat a server-supplied
filename as untrusted input:
- Remove directory separators and control characters.
- Reject
.and..as final names. - Keep the expected extension consistent with the media type.
- Impose a reasonable length limit.
- Never construct a server filesystem path directly from the value.
Browsers sanitize filenames independently, so exact renaming behavior differs between implementations.
Content-Type 与嗅探 #
Content-Type 描述表示形式。 A PDF should be
application/pdf, an SVG should be image/svg+xml, and arbitrary binary data
should be application/octet-stream.
X-Content-Type-Options: nosniffnosniff makes script and style fetches reject incompatible media types and
limits MIME-based reinterpretation in other protected fetch paths. It does not
repair an incorrect Content-Type, make arbitrary content safe, or force a
download. Serving active content under an incorrect benign type remains a
security problem because navigation and embedding rules depend on both the
declared type and the request context.
HTML 下载链接 #
download 属性表示链接的下载意图:
<a href="/exports/report.csv" download="report.csv">Download report</a>For HTTP(S) URLs, browsers honor download only for same-origin resources.
blob: and data: URLs are also eligible; CORS response headers do not make a
cross-origin HTTP URL eligible. A response Content-Disposition filename can
affect the suggested name, and attachment remains the reliable server-side
mechanism for a cross-origin download. Authorization must remain on the
download endpoint because hiding a URL behind a button does not protect it.
Blob URLs support generated client-side files:
const blob = new Blob([csv], { type: "text/csv;charset=utf-8" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = "report.csv";
document.body.append(link);
link.click();
link.remove();
setTimeout(() => URL.revokeObjectURL(url), 0);Revoke object URLs after the browser has started the navigation because each URL retains its backing data. Run this sequence from a user-initiated event; programmatic clicks do not bypass browser download policy.
自动化与安全限制 #
Sandboxed frames need the allow-downloads sandbox token, and browsers can
still block downloads without transient user activation or throttle repeated
downloads.
Cross-origin isolation, popup policy, mixed-content policy, and enterprise
configuration can introduce additional restrictions.
在每个受支持的浏览器中测试完整导航流程:
- Verify status,
Content-Type, andContent-Disposition. - Confirm the suggested filename and downloaded bytes.
- Exercise authenticated, redirected, and error responses.
- Verify that HTML error pages are not saved under a trusted file extension.
Header inspection alone cannot prove the user-visible outcome because the browser performs the final policy decision.
评论
在 GitHub 上阅读或评论(发表评论需要登录)