React & Expo - ファイルのアップロードとダウンロード方法
導入
Expo ベースのモバイル アプリでファイルをアップロードおよびダウンロードする方法について、明確な例を見つけるのに苦労しました。同じ課題に直面している他の人、または単に興味がある人を助けるために、私はこの投稿を書きました。
その過程で、理解することが重要な重要な概念を検討していきます。
- バッファ
- インテントフィルター
- MIME タイプ
- アプリケーション/オクテットストリーム
- マルチパート/フォームデータ
- さらに...
取り上げる内容:
- Fastify サーバーとのファイルの送受信。
- React Web アプリでのファイルのアップロード、ダウンロード、表示。
- React Native (Expo) モバイル アプリでのファイルのアップロード、ダウンロード、表示。
すべての コード と Postman コレクション は私の GitHub で入手できます。
サーバ
サーバーは Fastify (Express.js の最新バージョン) で実行されます。アプリを起動するには、次の手順を実行します:
- ターミナルを使用して /server に移動します
- npm install を使用して依存関係をインストールします
- 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 について詳しく学ぶ
- フォームデータを使用して複数のファイルをアップロード (/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 }; });
このエンドポイントはマルチパート/フォームデータリクエストを受け入れます。それ:
- リクエストからファイルを取得します。
- 各ファイルをバッファ (バイナリ データの JavaScript 表現) に変換します。
- ファイルを /upload ディレクトリに保存します。
たとえば、リクエストは次のようになります:
- 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 ではリクエストは次のようになります:
ウェブ (反応)
アプリを実行するには:
- ターミナルを使用して /web に移動します
- npm install を使用して依存関係をインストールします
- npm run dev を使用してアプリを起動します
Web アプリケーションのすべての機能は App.tsx に含まれています:
この 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 }; });
ユーザーが「ダウンロード」ボタンをクリックすると、アプリは次のようになります:
- /download エンドポイントを呼び出します。
- ファイルをバイナリ BLOB として受信します。
- 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 }; });
「ファイルをアップロード」ボタンをクリックした場合:
- uploadFile 関数が実行され、非表示の が作成されます。要素を追加し、ユーザーのクリックをシミュレートします。
- ユーザーが 1 つ以上のファイルを選択すると、それらのファイルは FormData オブジェクトに追加されます。
- リクエストは /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 を使用するよりも簡単です。ファイルをバイナリ データとしてリクエスト本文に直接送信し、リクエスト ヘッダーにファイル名を含めるだけです。
モバイル(エキスポ)
次のコマンドでアプリを起動できます:
- 端末のモバイル ディレクトリに移動します。
- 依存関係をインストールします: npm install
- 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 サイトの他の関連記事を参照してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

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

ホットトピック











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

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

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

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

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

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

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

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