ホームページ ウェブフロントエンド jsチュートリアル React & Expo - ファイルのアップロードとダウンロード方法

React & Expo - ファイルのアップロードとダウンロード方法

Dec 16, 2024 am 12:30 AM

導入

Expo ベースのモバイル アプリでファイルをアップロードおよびダウンロードする方法について、明確な例を見つけるのに苦労しました。同じ課題に直面している他の人、または単に興味がある人を助けるために、私はこの投稿を書きました。

その過程で、理解することが重要な重要な概念を検討していきます。

  • バッファ
  • インテントフィルター
  • MIME タイプ
  • アプリケーション/オクテットストリーム
  • マルチパート/フォームデータ
  • さらに...

取り上げる内容:

  • Fastify サーバーとのファイルの送受信。
  • React Web アプリでのファイルのアップロード、ダウンロード、表示。
  • React Native (Expo) モバイル アプリでのファイルのアップロード、ダウンロード、表示。

すべての コードPostman コレクション は私の GitHub で入手できます。

サーバ

React & Expo - How to Upload & Download Files

サーバーは Fastify (Express.js の最新バージョン) で実行されます。アプリを起動するには、次の手順を実行します:

  1. ターミナルを使用して /server に移動します
  2. npm install を使用して依存関係をインストールします
  3. npm run dev を使用してサーバーを実行します

app.js には 3 つの主要なエンドポイントがあります。

- ダウンロードエンドポイント (/download)

fastify.get("/download", async function handler(_, reply) {
  const fd = await open(FILE_TO_DOWNLOAD);
  const stream = fd.createReadStream();

  const mimeType = mime.lookup(FILE_TO_DOWNLOAD);

  console.log(`Downloading -> ${FILE_TO_DOWNLOAD}`);

  return reply
    .type(mimeType)
    .header(
      "Content-Disposition",
      `attachment; filename=${path.basename(FILE_TO_DOWNLOAD)}`
    )
    .send(stream);
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

このエンドポイントは、createReadStream() を使用して、example.webp をストリームとして送信します。 MIME タイプが含まれているため、クライアントはファイルの処理方法を知ることができます。たとえば、.webp の場合、これは image/webp になります。

?注: MIME タイプは、送信されるファイルの形式を定義します。これは、クライアントが正しく表示するのに役立ちます。
その他の MIME タイプを参照してください。

Content-Disposition ヘッダーは、コンテンツがクライアントにどのように表示されるかを定義します。付属品を含む。ファイル名=<ファイル名>ファイルをインラインで表示するのではなく、ダウンロードするようにブラウザーに要求します。直接表示するには、添付ファイルの代わりにインラインを使用します。
Content-Disposition について詳しく学ぶ

React & Expo - How to Upload & Download Files

- フォームデータを使用して複数のファイルをアップロード (/upload-multiples)

fastify.post("/upload-multiples", async function handler(request) {
  const parts = request.files();
  const uploadResults = [];

  for await (const file of parts) {
    const fileBuffer = await file.toBuffer();
    const filename = file.filename;
    const filePath = path.join(DIR_TO_UPLOAD, filename);

    await writeFile(filePath, fileBuffer);
    uploadResults.push({ filename, uploaded: true });
    console.log(`Uploaded -> ${filePath}`);
  }

  return { uploadedFiles: uploadResults };
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

このエンドポイントはマルチパート/フォームデータリクエストを受け入れます。それ:

  1. リクエストからファイルを取得します。
  2. 各ファイルをバッファ (バイナリ データの JavaScript 表現) に変換します。
  3. ファイルを /upload ディレクトリに保存します。

たとえば、リクエストは次のようになります:

React & Expo - How to Upload & Download Files

- Octet Stream (/upload-octet-stream) を使用したファイルのアップロード

fastify.get("/download", async function handler(_, reply) {
  const fd = await open(FILE_TO_DOWNLOAD);
  const stream = fd.createReadStream();

  const mimeType = mime.lookup(FILE_TO_DOWNLOAD);

  console.log(`Downloading -> ${FILE_TO_DOWNLOAD}`);

  return reply
    .type(mimeType)
    .header(
      "Content-Disposition",
      `attachment; filename=${path.basename(FILE_TO_DOWNLOAD)}`
    )
    .send(stream);
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

このエンドポイントは、リクエスト本文 (application/octet-stream) に単一のバイナリ ファイルが必要です。 multipart/form-data とは異なり、ファイルはすでにバイナリ データであるため、ディスクに直接書き込むことができます。

Postman ではリクエストは次のようになります:

React & Expo - How to Upload & Download Files

React & Expo - How to Upload & Download Files

ウェブ (反応)



React & Expo - How to Upload & Download Files

アプリを実行するには:

  1. ターミナルを使用して /web に移動します
  2. npm install を使用して依存関係をインストールします
  3. npm run dev を使用してアプリを起動します

Web アプリケーションのすべての機能は App.tsx に含まれています:

React & Expo - How to Upload & Download Files

この React アプリは 3 つの主要な機能を提供します:

- ファイルのダウンロード/表示

fastify.post("/upload-multiples", async function handler(request) {
  const parts = request.files();
  const uploadResults = [];

  for await (const file of parts) {
    const fileBuffer = await file.toBuffer();
    const filename = file.filename;
    const filePath = path.join(DIR_TO_UPLOAD, filename);

    await writeFile(filePath, fileBuffer);
    uploadResults.push({ filename, uploaded: true });
    console.log(`Uploaded -> ${filePath}`);
  }

  return { uploadedFiles: uploadResults };
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ユーザーが「ダウンロード」ボタンをクリックすると、アプリは次のようになります:

  1. /download エンドポイントを呼び出します。
  2. ファイルをバイナリ BLOB として受信します。
  3. BLOB から objectURL を作成し、ブラウザーがアクセスできる一時 URL として機能します。

動作は、サーバーから返された Content-Disposition ヘッダーによって異なります。

  • Content-Disposition にインラインが含まれる場合、ファイルは新しいタブに表示されます。
  • 添付ファイルが含まれている場合、ファイルは自動的にダウンロードされます。

ダウンロードをトリガーするために、アプリは一時的な ファイルを作成します。要素に href を objectURL に設定し、プログラムでクリックして、ユーザーのダウンロード アクションをシミュレートします。

- フォームデータを使用したファイルのアップロード

fastify.post("/upload-octet-stream", async function handler(request) {
  const filename = request.headers["x-file-name"] ?? "unknown.text";

  const data = request.body;
  const filePath = path.join(DIR_TO_UPLOAD, filename);

  await writeFile(filePath, data);

  return { uploaded: true };
});
ログイン後にコピー
ログイン後にコピー

「ファイルをアップロード」ボタンをクリックした場合:

  1. uploadFile 関数が実行され、非表示の が作成されます。要素を追加し、ユーザーのクリックをシミュレートします。
  2. ユーザーが 1 つ以上のファイルを選択すると、それらのファイルは FormData オブジェクトに追加されます。
  3. リクエストは /upload-multiples エンドポイントに送信され、multipart/form-data 経由でファイルを受け取ります。

これにより、サーバーはアップロードされたファイルを適切に処理し、保存できるようになります。

- Octet Streamを使用したファイルのアップロード

  const downloadFile = async () => {
    const response = await fetch(DOWNLOAD_API);

    if (!response.ok) throw new Error("Failed to download file");

    const blob = await response.blob();

    const contentDisposition = response.headers.get("Content-Disposition");

    const isInline = contentDisposition?.split(";")[0] === "inline";
    const filename = contentDisposition?.split("filename=")[1];

    const url = window.URL.createObjectURL(blob);

    if (isInline) {
      window.open(url, "_blank");
    } else {
      const a = document.createElement("a");
      a.href = url;
      a.download = filename || "file.txt";
      a.click();
    }

    window.URL.revokeObjectURL(url);
  };
ログイン後にコピー
ログイン後にコピー

このアプローチは、multipart/form-data を使用するよりも簡単です。ファイルをバイナリ データとしてリクエスト本文に直接送信し、リクエスト ヘッダーにファイル名を含めるだけです。

モバイル(エキスポ)



React & Expo - How to Upload & Download Files

次のコマンドでアプリを起動できます:

  1. 端末のモバイル ディレクトリに移動します。
  2. 依存関係をインストールします: npm install
  3. npm run android または npm run ios でプロジェクトを実行します

メイン ロジックは App.tsx にあり、ここで次の内容がレンダリングされます。

fastify.get("/download", async function handler(_, reply) {
  const fd = await open(FILE_TO_DOWNLOAD);
  const stream = fd.createReadStream();

  const mimeType = mime.lookup(FILE_TO_DOWNLOAD);

  console.log(`Downloading -> ${FILE_TO_DOWNLOAD}`);

  return reply
    .type(mimeType)
    .header(
      "Content-Disposition",
      `attachment; filename=${path.basename(FILE_TO_DOWNLOAD)}`
    )
    .send(stream);
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

ファイルを新しいビューで表示するには (ブラウザーが新しいタブでファイルを開く場合と同様)、応答を BLOB として読み取り、FileReader を使用してそれを Base64 に変換する必要があります。

キャッシュ ディレクトリ (アプリのみがアクセスできるプライベート ディレクトリ) にファイルを書き込み、IntentLauncher またはユーザーが iOS を使用している場合は共有を使用してそのファイルを表示します。

- ダウンロードファイル

fastify.post("/upload-multiples", async function handler(request) {
  const parts = request.files();
  const uploadResults = [];

  for await (const file of parts) {
    const fileBuffer = await file.toBuffer();
    const filename = file.filename;
    const filePath = path.join(DIR_TO_UPLOAD, filename);

    await writeFile(filePath, fileBuffer);
    uploadResults.push({ filename, uploaded: true });
    console.log(`Uploaded -> ${filePath}`);
  }

  return { uploadedFiles: uploadResults };
});
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

これは Web プロセスに似ていますが、FileReader を使用して BLOB を Base64 として読み取り、ユーザーがファイルを保存したい場所にファイルをダウンロードする許可を求める必要があります。

- フォームデータを使用したファイルのアップロード

fastify.post("/upload-octet-stream", async function handler(request) {
  const filename = request.headers["x-file-name"] ?? "unknown.text";

  const data = request.body;
  const filePath = path.join(DIR_TO_UPLOAD, filename);

  await writeFile(filePath, data);

  return { uploaded: true };
});
ログイン後にコピー
ログイン後にコピー

DocumentPicker を使用してユーザーがファイルを選択できるようにし、FormData を使用して選択したファイルをリクエストに追加します。プロセスは非常に簡単です。

- ファイルをオクテット ストリームとしてアップロード

  const downloadFile = async () => {
    const response = await fetch(DOWNLOAD_API);

    if (!response.ok) throw new Error("Failed to download file");

    const blob = await response.blob();

    const contentDisposition = response.headers.get("Content-Disposition");

    const isInline = contentDisposition?.split(";")[0] === "inline";
    const filename = contentDisposition?.split("filename=")[1];

    const url = window.URL.createObjectURL(blob);

    if (isInline) {
      window.open(url, "_blank");
    } else {
      const a = document.createElement("a");
      a.href = url;
      a.download = filename || "file.txt";
      a.click();
    }

    window.URL.revokeObjectURL(url);
  };
ログイン後にコピー
ログイン後にコピー

Application/octet-stream としてアップロードするのは、FormData を使用するよりもさらに簡単です。ヘッダーにファイルの詳細とコンテンツ タイプを設定し、ファイルをリクエスト本文に追加するだけです。

結論

プラットフォーム間でファイルを表示、ダウンロード、アップロードする方法は少しわかりにくいかもしれません。この投稿では最も一般的なものを説明しました。

お役に立てれば幸いです?

@twitter をフォローしてください

以上がReact & Expo - ファイルのアップロードとダウンロード方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

javascriptの分解:それが何をするのか、なぜそれが重要なのか javascriptの分解:それが何をするのか、なぜそれが重要なのか Apr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

JavaScriptの進化:現在の傾向と将来の見通し JavaScriptの進化:現在の傾向と将来の見通し Apr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

JavaScriptエンジン:実装の比較 JavaScriptエンジン:実装の比較 Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

Python vs. JavaScript:学習曲線と使いやすさ Python vs. JavaScript:学習曲線と使いやすさ Apr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

JavaScript:Web言語の汎用性の調査 JavaScript:Web言語の汎用性の調査 Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合) next.jsを使用してマルチテナントSaaSアプリケーションを構築する方法(フロントエンド統合) Apr 11, 2025 am 08:22 AM

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

C/CからJavaScriptへ:すべてがどのように機能するか C/CからJavaScriptへ:すべてがどのように機能するか Apr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合) next.jsを使用してマルチテナントSaaSアプリケーションを構築する(バックエンド統合) Apr 11, 2025 am 08:23 AM

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます

See all articles