JavaScript >> Javascript 文檔 >  >> JavaScript

如何使用操縱桿同時將文件上傳到多個位置

如何使用操縱桿的上傳功能將文件上傳到多個目的地。

開始使用

在本教程中,我們將使用 CheatCode 的全棧 JavaScript 框架 Joystick。 Joystick 將前端 UI 框架與用於構建應用的 Node.js 後端結合在一起。

首先,我們要通過 NPM 安裝 Joystick。確保在安裝之前使用 Node.js 16+ 以確保兼容性(如果您需要學習如何安裝 Node.js 或在計算機上運行多個版本,請先閱讀本教程):

終端

npm i -g @joystick.js/cli

這將在您的計算機上全局安裝操縱桿。安裝好之後,接下來我們新建一個項目:

終端

joystick create app

幾秒鐘後,您將看到一條消息已註銷到 02 進入你的新項目並運行 10 .在你做之前,我們需要安裝一個依賴,27

終端

cd app && npm i uuid

我們將使用它來生成一個任意 UUID,我們可以將其與上傳一起傳遞,以演示通過您的上傳傳遞數據。安裝好之後,你就可以啟動你的服務器了:

終端

joystick start

在此之後,您的應用應該可以運行了,我們可以開始了。

設置 Amazon S3 存儲桶

對於本教程,我們將文件上傳到的兩個位置之一將是 Amazon S3(另一個將是應用程序內的本地文件夾)。對於 S3,我們需要確保我們有一些東西:

  1. 一個亞馬遜網絡服務帳戶。
  2. Amazon IAM 用戶提供用於訪問存儲桶的憑證。
  3. 一個 Amazon S3 存儲桶。

如果您已經可以訪問這些,您可以跳到下面的“在服務器上連接上傳器”部分。

如果您沒有這些,請首先前往 Amazon Web Services 並在此處創建一個新帳戶。

註冊後,請確保您已完成添加賬單信息的所有步驟,然後前往 IAM 安全憑證頁面。在左側菜單中,單擊“訪問管理”子標題下的“用戶”選項。

在此頁面的右上角,單擊藍色的“添加用戶”按鈕。在下一頁的“用戶名”框中,輸入您的 IAM(身份訪問管理)用戶的用戶名,然後在“選擇 AWS 訪問類型”下勾選“訪問密鑰 - 編程訪問”旁邊的框。設置好後,點擊頁面右下角的“下一步:權限”。

在下一個屏幕上,單擊標有“直接附加現有策略”的第三個框,然後在頁面中間“過濾策略”旁邊的搜索框中,輸入“s3full”以將列表過濾到 32 選項。勾選此項旁邊的框,然後點擊頁面右下角的“下一步:標籤”按鈕。

可以跳過“標籤”頁面以及之後的頁面(除非您熟悉這些並想完成它們)。在這些之後,您的 IAM 用戶的憑據將被顯示。

注意:IAM 憑證就像竊賊的黃金一樣。在任何情況下都不要將它們放入公共 Github 存儲庫或將它們提供給您不認識/不信任的人。 很容易洩露這些密鑰,並在月底發現亞馬遜的意外賬單,其中包含您沒有產生的費用(我根據經驗說話)。

最好將這些憑據存儲在安全位置,例如 1Password、LastPass 或您信任的其他密碼管理工具。

設置好憑據後,返回我們從上面開始的“用戶”列表,然後單擊您剛剛創建的用戶以顯示“摘要”頁面。從這裡,您需要復制頁面標題下方的長“用戶 ARN”字符串。接下來我們將使用它來設置您的存儲桶。

複製完成後,在頁面頂部(“AWS”徽標右側)的搜索框中輸入 s3,然後選擇搜索結果中“服務”下方顯示的第一個選項。

在下一頁上,單擊頁面右上角的橙色“創建存儲桶”按鈕。在此頁面中,我們需要填寫以下字段:

  1. 對於“存儲桶名稱”,輸入一個唯一的名稱(存儲桶名稱對於您為第二個選項選擇的區域必須是唯一的)來描述您的存儲桶將包含什麼。
  2. 對於“AWS 區域”,請選擇最接近您的大多數用戶或最接近您自己的區域。
  3. 在“對象所有權”下,選中“已啟用 ACL”框。儘管不建議這樣做,但我們需要這樣做才能在您的應用中針對每個上傳者自定義權限。
  4. 對於“阻止公共訪問...”,此選項由您決定。如果您的存儲桶不會存儲敏感文件或您希望保密的文件,您可以取消選中此框(並選中執行時出現的“我確認”警告)。對於本教程其餘部分使用的存儲桶,我們已取消選中此框以允許使用公共對象。

設置完成後,您可以跳過其他設置並單擊頁面底部的“創建存儲桶”。創建存儲桶後,在存儲桶列表中找到它並單擊它以在儀表板中顯示它。在此處,找到頁面頂部的“權限”選項卡,在此選項卡上,找到並單擊“存儲桶策略”塊中的“編輯”按鈕。

在彈出的框中,您將要粘貼以下語句,替換 47 帶有您剛剛創建的存儲桶名稱和 59 的佔位符 使用我們在上面複製的“用戶 ARN”。

示例 Amazon S3 存儲桶策略

{
  "Id": "Policy1654277614273",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1654277612532",
      "Action": "s3:*",
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::<bucket-name>/*",
      "Principal": {
        "AWS": [
          "<user arn you copied>"
        ]
      }
    }
  ]
}

為您的存儲桶和用戶定制此內容後,向下滾動並單擊橙色的“保存更改”按鈕。設置完成後,我們剛剛完成的是允許我們剛剛創建的 IAM 用戶憑證擁有對我們剛剛創建的存儲桶的完全訪問權限。當我們接下來配置我們的上傳器並設置我們上面提示的“ACL”(AWS-speak 中的“訪問控制列表”)時,這將發揮作用。

在服務器上連接上傳器

為了支持在 Joystick 應用中上傳文件,我們需要在我們的 62 中在服務器上定義一個上傳器 文件。讓我們看一下基本設置並逐步完成:

/index.server.js

import node from "@joystick.js/node";
import api from "./api";

node.app({
  api,
  uploaders: {
    photos: {
      providers: ['local', 's3'],
      local: {
        path: 'uploads',
      },
      s3: {
        region: 'us-east-1',
        accessKeyId: joystick?.settings?.private?.aws?.accessKeyId,
        secretAccessKey: joystick?.settings?.private?.aws?.secretAccessKey,
        bucket: 'cheatcode-tutorials',
        acl: 'public-read',
      },
      mimeTypes: ['image/jpeg', 'image/png', 'image/svg+xml', 'image/webp'],
      maxSizeInMegabytes: 5,
      fileName: ({ input, fileName, mimeType }) => {
        // NOTE: Return the full path and file name that you want the file to be stored in
        // relative to the provider.
        return `photos/${input?.photoId}_${fileName}`;
      },
    },
  },
  routes: { ... },
});

這是我們支持多位置上傳所需的一切。首先,我們調用 7881 導入的函數 為我們啟動服務器的包(在幕後使用 Express.js)。對於該函數,我們可以傳遞對像上的選項來自定義應用的行為。

在這裡,99 選項接受一個對象,其中每個屬性定義我們希望在我們的應用程序中支持的上傳器之一(在這裡,我們定義了一個名為 100 的上傳器 )。我們將上傳者的對像或“定義”傳遞給該屬性。

在頂部,我們傳遞一個 115 字符串數組,用於指定我們希望上傳的位置(操縱桿自動將文件的上傳路由到這些提供程序)。在這裡,我們可以指定一個或多個接收上傳的提供者。在這種情況下,我們要上傳到兩個位置:我們的本地機器和 Amazon S3。

基於122 我們通過了,接下來,我們需要為那些特定的提供者定義配置。

對於 132 ,我們傳遞一個帶有單個對象 141 的對象 它指定了存儲文件的本地路徑(相對於我們應用程序的根目錄)。

對於 154 , 事情有點多。在這裡,我們需要指定幾個不同的屬性:

  • 164 這是我們存儲桶所在區域的 AWS 區域簡碼。
  • 178 這是您之前與 IAM 用戶一起生成的“訪問密鑰 ID”。
  • 182 這是您之前與 IAM 用戶一起生成的“秘密訪問密鑰”。
  • 197 這是您希望存儲文件的存儲桶的名稱。
  • 208 這是您要應用於通過此上傳器上傳的所有文件的“訪問控制列表”或包羅萬象的權限。對於我們的示例,我們使用 217 這意味著文件對於公共用戶是只讀的。

注意 :對於 229230 這裡的值,請注意我們從 243 中提取這些值 .在 Joystick 應用中,您可以在 257 中指定應用中每個環境的設置 應用程序根目錄下的文件(其中 267 是您的應用支持的某些環境)。

在這裡,因為我們在 279 環境中,我們希望這些值在我們的 281 中定義 文件。這是此文件的更新版本(您需要填寫您的 290306 您之前從 AWS 獲得的):

/settings.development.json

{
  "config": {
    "databases": [
      {
        "provider": "mongodb",
        "users": true,
        "options": {}
      }
    ],
    "i18n": {
      "defaultLanguage": "en-US"
    },
    "middleware": {},
    "email": {
      "from": "",
      "smtp": {
        "host": "",
        "port": 587,
        "username": "",
        "password": ""
      }
    }
  },
  "global": {},
  "public": {},
  "private": {
    "aws": {
      "accessKeyId": "",
      "secretAccessKey": ""
    }
  }
}

Joystick 中的設置文件支持四個根屬性:319 , 322 , 336 , 和 340 .在這裡,我們使用 359 只能在服務器上訪問以存儲我們的 AWS 憑證的對象(我們不想將這些放入 367373 因為如果我們這樣做,它們將暴露給瀏覽器)。

回到我們的上傳器定義中,在 385 之後 ,我們有一些特定於上傳器的通用設置。其中包括:

  • 395 這是一個字符串數組,指定此上傳器支持的 MIME 類型(例如,我們僅在此處傳遞圖像 MIME 類型以避免上傳視頻、文檔或音頻文件等內容)。
  • 404 此上傳者允許的最大文件大小(以兆字節為單位)。超過此限制的文件將被上傳者拒絕。
  • 415 一個函數,它讓我們有機會為我們上傳的文件自定義路徑/文件名。此函數接收包含 422 的對象 , 431 , 442 , 和 458 對於上傳的文件以及 461 我們從客戶端傳遞(稍後會詳細介紹)。在這裡,我們返回一個在文件夾 471 中嵌套上傳的路徑 和前綴 484 上傳文件的 494 通過505 對象。

而已!有了這個,現在我們在服務器上準備好了一個上傳器。讓我們跳到客戶端,看看我們實際上是如何上傳文件的。

在客戶端調用上傳者

幸運的是,從客戶端調用上傳器非常簡單:我們只需要調用一個函數 513 來自 528 包(我們用來定義我們的組件的同一個)。為了讓我們的工作更輕鬆,我們將重用現有的 531 當我們運行 540 時已經為我們創建的文件 早一點。

讓我們用下面的內容替換它的現有內容並逐步完成它:

/ui/pages/index/index.js

import ui, { upload } from "@joystick.js/ui";
import { v4 as uuid } from "uuid";

const Index = ui.component({
  state: {
    uploads: [],
    progress: 0,
  },
  events: {
    'change input[type="file"]': (event, component) => {
      component.setState({ urls: [], }, () => {
        upload('photos', {
          files: event.target.files,
          input: {
            // NOTE: Arbitrary, just to demonstrate passing data alongside your upload.
            // This is accessible within the `fileName` function on your uploader definition.
            photoId: uuid(),
          },
          onProgress: (progress = 0, provider = '') => {
            component.setState({ progress, provider });
          },
        }).then((uploads) => {
          component.setState({ progress: 0, uploads });
        }).catch((errors) => {
          console.warn(errors);
        });
      });
    },
  },
  css: `
    .progress-bar {
      width: 100%;
      height: 10px;
      border-radius: 30px;
      background: #eee;
      margin-top: 30px;
    }

    .progress-bar .progress {
      height: 10px;
      background: #ffcc00;
      border-radius: 30px;
    }
  `,
  render: ({ when, state, each }) => {
    return `
      <div>
        <input type="file" />
        ${when(state.progress > 0, `
          <div class="progress-bar">
            <div class="progress" style="width:${state.progress}%;"></div>
          </div>
        `)}
        ${when(state.uploads?.length > 0, `
          <ul>
            ${each(state.uploads, (upload) => {
              return `<li>${upload.provider}: ${upload.url ? `<a href="${upload.url}">${upload.url}</a>` : upload.error}</li>`;
            })}
          </ul>
        `)}
      </div>
    `;
  },
});

export default Index;

557 開始 函數,在這裡,我們指定了一些我們想要為我們的組件呈現的 HTML。這裡重要的部分是 563 標籤是我們如何選擇要從我們的計算機上傳的文件。

在此之下,使用 574 渲染函數(這是用於傳遞給組件的 588 的特殊“上下文”函數的名稱 操縱桿中的函數)說“當 593 的值 大於 604 ,渲染這個 HTML。”“這個 HTML”在這裡是一個進度條的標記,它將在我們的上傳完成時填充。

為了模擬填充,我們添加了一個內聯 617 設置 CSS 629 的屬性 內部 633 上的動態屬性 645 的值的元素 與 653 連接 百分比符號(操縱桿自動為我們提供上傳完成百分比作為浮點/十進制值)。

在此之下,再次使用 660 函數,如果我們看到 675 長度大於 680 (意味著我們已經上傳了一個文件並收到了我們所有提供者的響應),我們想要渲染一個 699 列出由 返回的提供程序和 URL 的標籤 我們文件的那些提供者。

在這裡,我們使用 705 render 函數,顧名思義,它幫助我們為 each 渲染一些 HTML 數組中的項。在這裡,對於 711 中的每個預期對象 ,我們返回一個 725 標籤告訴我們 732 對於特定的上傳(例如,743758 ) 以及提供者返回的 URL。

在此之上,利用 763 我們組件上的選項,我們為我們的進度條傳遞了一些簡單的樣式(隨意複製它並為您自己的應用程序調整它)。

這裡重要的部分是 775 784 上方的塊 .在這裡,我們定義了我們想要在 within 中監聽的 JavaScript DOM 事件監聽器 我們的組件(即,操縱桿自動將此處定義的事件偵聽器限定為 this 零件)。到 797 ,我們傳遞一個對象,其屬性定義為一個字符串,將兩個值組合在一起,中間有一個空格:DOM的類型 807 我們要監聽 811 我們想監聽事件on (825 )。

在這種情況下,我們要監聽 830 我們的 848 上的事件 元素。當這種情況發生時,這意味著我們的用戶已經選擇了他們想要上傳的文件;觸發上傳的最佳時機 那個文件。當在我們的文件輸入中檢測到此事件時,Joystick 將調用該函數。

在裡面,首先,我們調用 858 清空我們的 860 值,假設我們多次運行上傳程序並且不想混淆響應 URL。

接下來,在裡面,我們調用 873 我們從 886 導入的函數 之上。此功能與 890 幾乎相同 和 908 Joystick 中用於調用在 Joystick 應用中定義為 getter 和 setter 的 API 端點的函數。

它需要兩個參數:

  1. 我們在將處理此上傳的服務器上定義的上傳者的名稱(例如,在這裡,我們傳遞 910 因為這是我們在服務器上用於上傳器的名稱)。
  2. 提供 924 的選項對象 我們要上傳,任何雜項 933 我們想要傳遞的數據,以及一個 949 每當我們的上傳進度發生變化時都會調用該函數。

對於 959 在這裡,我們只是傳遞 965 其中包含 979 上提供的瀏覽器文件數組 文件輸入的事件(這是必需的,因為它告訴操縱桿 which 我們正在嘗試上傳的文件)。對於 980 ,只是為了演示,我們傳遞一個具有單個屬性992的對象 設置為調用 1000 .這是來自 1016 的函數 我們之前安裝的包(請參閱此文件頂部的導入)生成隨機 UUID 值。雖然這不是必要的 ,它演示瞭如何獲取與我們的上傳器一起傳遞的額外數據,以便與 1028 一起使用 上傳器定義中的函數。

對於 1038 ,每當 Joystick 從服務器接收到一個進度事件時,它就會調用我們傳遞給 1048 的函數 這裡有兩個參數:第一,1058 上傳的百分比和 1063 這是進度所屬的提供者的名稱。例如這裡,因為我們要上傳到 10741086 ,我們希望它會被一些 1091 調用 百分比和 11041114 對於 1127 價值。如果我們願意,這使我們能夠跟踪每個提供商的進度。

最後,因為我們期望 1138 為了返回一個 JavaScript Promise,我們添加了一個 1148 回調和 1157 最後回調。如果我們的上傳完成沒有任何問題,1161 回調將觸發,接收描述每個提供者的上傳結果的一組對象(即 1174 的一個對象 , 1183 的一個對象 等)。

因為我們在 1190 中呈現我們的上傳列表 函數,在這裡,我們只取原始數組並將其設置在 1206 (請記住,這就是我們在 1217 中引用的內容 函數)。

所以很明顯,在我們傳遞給 1221 的選項對象的最頂部 我們提供了一個 1236 為我們的兩個狀態值設置一些默認值的對象:1247 作為一個空數組 12501269 作為 1276 .

應該這樣做!現在,如果我們從我們的計算機中選擇一個圖像文件並上傳它,我們應該會看到我們的進度條已填充,並在完成後呈現到屏幕上的 URL 列表。

總結

在本教程中,我們學習瞭如何將上傳添加到操縱桿應用程序。我們學習瞭如何在服務器上定義一個上傳器,指定多個提供者/目的地,為每個提供者傳遞配置,以及如何自定義允許的 1288 , 1293 , 和 1303 對於我們正在上傳的文件。在客戶端,我們學習瞭如何調用上傳器,處理上傳進度以及上傳完成後生成的 URL。


Tutorial JavaScript 教程
  1. 如何使用 jQuery 或純 JS 重置所有復選框?

  2. [已解決]即使驗證要求無效,數據仍在發送,解決此問題的最佳方法是什麼?

  3. 待辦事項列表

  4. 首先看一下 deno

  5. React/Redux 連接表單的單元和集成測試完整指南

  6. JavaScript 如何在幕後工作 - 執行上下文和調用堆棧

  7. 使用 Cypress 測試前端性能

  1. MobX 與 React 和 TypeScript

  2. Ava 和 React 測試庫

  3. 在 Nest.js 中組織導入

  4. 今天我學習瞭如何在 CSS(和 JavaScript)中為文本漸變設置動畫

  5. React 中的 localStorage 非常簡單的介紹

  6. 最有用的 npm 命令

  7. Datetimepicker 下拉菜單未全尺寸顯示

  1. 在 Angular 中進行 Linktree 克隆

  2. NGConf 2019 - 主題演講第一天

  3. 只克隆 GIT 中的子文件夾🔥

  4. 使用 NodeJS 進行網頁抓取:綜合指南 [第 1 部分]