From d956339c8fc31f94ca79fded58c7357addaf0a68 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Tue, 9 Jul 2024 03:52:47 -0400 Subject: [PATCH] Notes on insecure (HTTP) downloads --- docz/docs/03-demos/27-local/01-file.md | 18 +++++++++++++++++- docz/docs/09-miscellany/02-errors.md | 17 +++++++++++++++++ docz/static/files/dlblk.png | Bin 0 -> 21561 bytes 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 docz/static/files/dlblk.png diff --git a/docz/docs/03-demos/27-local/01-file.md b/docz/docs/03-demos/27-local/01-file.md index 38773cd..6ce5c98 100644 --- a/docz/docs/03-demos/27-local/01-file.md +++ b/docz/docs/03-demos/27-local/01-file.md @@ -282,6 +282,19 @@ client browser. Some APIs do not give any feedback. ::: +:::caution pass + +In insecure (HTTP) contexts, Google Chrome will block downloads by default. The +following screenshot was taken in Chrome 126.0.6478.127: + +![Insecure download blocked](pathname:///files/dlblk.png) + +This is a browser limitation and no pure JavaScript library can work around the +issue. See [Issue #3145](https://git.sheetjs.com/sheetjs/sheetjs/issues/3145) in +the SheetJS bug tracker for more details. + +::: + ### HTML5 Download Attribute _Writing Files_ @@ -436,6 +449,8 @@ drop_dom_element.addEventListener("dragenter", suppress, false); At the time of writing, browser support was fairly limited. Chrome introduced the feature in version 86. Safari did not support File System Access API. +The File System Access API is only available in secure (HTTPS) contexts.[^4] + ::: :::caution pass @@ -819,4 +834,5 @@ Desktop and mobile apps have their own specific APIs covered in separate demos: [^1]: See ["Input Type" in "Reading Files"](/docs/api/parse-options#input-type) [^2]: See ["Supported Output Formats" type in "Writing Files"](/docs/api/write-options#supported-output-formats) -[^3]: See ["Buffers and TypedArrays"](https://nodejs.org/api/buffer.html#buffers-and-typedarrays) in the NodeJS documentation. \ No newline at end of file +[^3]: See ["Buffers and TypedArrays"](https://nodejs.org/api/buffer.html#buffers-and-typedarrays) in the NodeJS documentation. +[^4]: See [issue 3145 in the SheetJS bug tracker](https://git.sheetjs.com/sheetjs/sheetjs/issues/3145#issuecomment-11074) for more details. Special thanks to `@sjoenH`! \ No newline at end of file diff --git a/docz/docs/09-miscellany/02-errors.md b/docz/docs/09-miscellany/02-errors.md index cf0a2b0..7adcedf 100644 --- a/docz/docs/09-miscellany/02-errors.md +++ b/docz/docs/09-miscellany/02-errors.md @@ -474,3 +474,20 @@ to an `index.html` file, bypassing any third-party post-processing There are known bugs with the SWC minifier (used in Next.js 13+). The original minifier can be enabled by setting `swcMinify: false` in `next.config.js`. + +#### This file should be served over HTTPS + +`writeFile` uses platform APIs to download files. In browsers, `writeFile` uses +the [`download` attribute](/docs/demos/local/file/#html5-download-attribute). + +Newer versions of Google Chrome and other browsers will block these downloads +from "insecure contexts" (when served over HTTP rather than HTTPS). Users may be +presented with the option to "keep" or "save" the file: + +![Download blocked](pathname:///files/dlblk.png) + +These limitations are enforced by the browser. It is strongly recommended to +serve websites over HTTPS when possible. + +See [issue #3145](https://git.sheetjs.com/sheetjs/sheetjs/issues/3145) for a +longer discussion. diff --git a/docz/static/files/dlblk.png b/docz/static/files/dlblk.png new file mode 100644 index 0000000000000000000000000000000000000000..284930bd9d2c8f72022247d21cf8c67814a88421 GIT binary patch literal 21561 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

jqIyjs2T+r0u0J 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 P=x^pQE0b47e?|Wv?ft#* literal 0 HcmV?d00001