質問:
両方のサーバーをブロックせずに、アップロードされたファイルのサーバーへの書き込み中のファイル サイズをリアルタイムで取得します。
コンテキスト:
ファイルまたは Blob 本文を含む fetch() の POST リクエストを使用してサーバーに書き込む際の、クライアントのブラウザーでのファイル アップロードの進行状況。
要件:
サーバー ファイルシステムへの書き込み中のファイル サイズを text/event-stream として表示します。ファイルのアップロード中にクエリ文字列パラメータとして指定されたすべてのバイトが書き込まれたときに停止します。ファイル サイズは現在、ファイルがサーバーに書き込まれた後に呼び出される別のスクリプトから取得されます。
実装:
最初は PHP を使用して試みましたが、問題が発生しました。未定義の HTTP_LAST_EVENT_ID と誤ったファイル サイズが報告されることによるエラー。また、bash、c、nodejs、python などのさまざまなアプローチや言語も実験しました。
解決策:
<code class="php">clearstatcache(true, $upload); $data = filesize($upload);</code>
<code class="php">// Check if the header's been sent to avoid `PHP Notice: Undefined index: HTTP_LAST_EVENT_ID in stream.php on line ` // php 7+ //$lastId = $_SERVER["HTTP_LAST_EVENT_ID"] ?? 0; // php < 7 $lastId = isset($_SERVER["HTTP_LAST_EVENT_ID"]) ? intval($_SERVER["HTTP_LAST_EVENT_ID"]) : 0; $upload = $_GET["filename"]; $data = 0; // if file already exists, its initial size can be bigger than the new one, so we need to ignore it $wasLess = $lastId != 0; while ($data < $_GET["filesize"] || !$wasLess) { // system calls are expensive and are being cached with assumption that in most cases file stats do not change often // so we clear cache to get most up to date data clearstatcache(true, $upload); $data = filesize($upload); $wasLess |= $data < $_GET["filesize"]; // don't send stale filesize if ($wasLess) { sendMessage($lastId, $data); $lastId++; } // not necessary here, though without thousands of `message` events will be dispatched //sleep(1); // millions on poor connection and large files. 1 second might be too much, but 50 messages a second must be okay usleep(20000); }</code>
<code class="javascript">const [fileId, request, source] = [ Math.random().toString(36).substr(2), new Request(`${url}?fileId=${fileId}&size=${filesize}`, { method: "POST", headers: headers, body: file }), new EventSource(`${stream}?fileId=${fileId}`) ];</code>
<code class="php">function setUnique(string $id, int $size) { // implement with your storage of choice } function updateProgress(string $id, int $processed) { // implement with your storage of choice }</code>
<code class="php">list($progress, $size) = getProgress($_GET["fileId"]);</code>
重要な注意事項:
以上がサーバーバインドアップロードのリアルタイムファイルサイズを取得するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。