簡體   English   中英

Nodejs - 使用預簽名 url 從 s3 存儲桶中下載文件

[英]Nodejs - React download file from s3 bucket using pre-signed url

我正在嘗試制作一個 onClick 按鈕以使用 pre-si.net url 從 S3 存儲桶下載文件。當我收到我的 url 時出現問題。我想要一個自動重定向或類似的。 換句話說,我如何在取回我的簽名 url 后下載下載文件?

這是我的文件清單

onClick 事件在下載按鈕上。

redux行動

Redux 動作調用我的 nodejs 路由api 路由 nodejs

要求預簽名 url 然后將其發送到我的 redux reducer。

現在在我的前端頁面中,我得到了我的鏈接,但我想要一個自動重定向來開始文件下載。 組件的一部分

希望我的第一篇文章不會太亂。

我通過redux動作解決了我的問題。 一鍵式調用我的操作,操作者將返回我的預簽名URL,然后自動單擊鏈接。 當我將其上傳到S3時,會觸發具有原始文件名的下載事件。

 export const downDoc = (docId) => async dispatch => { const res = await axios({ url: 'myApiCall', method: 'GET', responseType: 'blob' }) .then((response) => { console.log(response) const url = window.URL.createObjectURL(new Blob([response.data])); const link = document.createElement('a'); link.href = url; link.setAttribute('download', `${docId.originalName}`); document.body.appendChild(link); link.click(); }); 

另一個答案直接進行 DOM 操作,創建一個 blob,它看起來好像在將整個文件發送給用戶之前將整個文件緩沖在 memory 中,並且每次下載時都會創建一個新鏈接。 做的反應是:

const downloadFileRef = useRef<HTMLAnchorElement | null>(null);
const [downloadFileUrl, setDownloadFileUrl] = useState<string>();
const [downloadFileName, setDownloadFileName] = useState<string>();

const onLinkClick = (filename: string) => {
    axios.get("/presigned-url")
      .then((response: { url: string }) => {
        setDownloadFileUrl(response.url);
        setDownloadFileName(filename);
        downloadFileRef.current?.click();
      })
      .catch((err) => {
        console.log(err);
      });
  };

return (
<>
   <a onClick={() => onLinkClick("document.pdf")} aria-label="Download link">
       Download
   </a>
   <a
        href={downloadFileUrl}
        download={downloadFileName}
        className="hidden"
        ref={downloadFileRef}
   />
</>)

有關更多信息,請參見此處https://levelup.gitconnected.com/react-custom-hook-typescript-to-download-a-file-through-api-b766046db18a

我這樣做的方式是不同的,並且具有能夠在下載文件時看到下載進度的優勢。 如果您正在下載一個大文件,那么當您立即看到反饋時,它會對用戶體驗產生影響。

我所做的是:

  1. 創建 S3 預簽名 URL 時,我將content-disposition為“附件”
  2. 我使用錨元素來下載實際項目<a url='https://presigned-url' download>Download me</a>

其他人提到在 DOM 或 React 中模擬點擊,但另一種選擇是使用window.open() 您可以將 target 屬性設置為_blank以打開選項卡,但您確實需要在單擊事件中使用window.open()以防止彈出窗口阻止程序停止該功能。 這里有一些關於這個主題的很好的討論。 我發現這是比模擬點擊事件更好的解決方案。

這是一個示例(盡管可能需要更多,具體取決於您獲取 signed_url 的方式)。

function downloadDocument() {
  const signedurlPromise = fetch("/signed_url")
  signedurlPromise.then((response) => {
      window.open(response.signed_url, "_blank");
  })
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM