私の問題は、に似ています。この1ので、ここで私が得たものだが、それは多くのコンテキストまたは詳細なしで古いポストでした。
コンポーネントがダウンロードファイルメソッドを呼び出し、次にダウンロードファイルサービスを呼び出すと、サービスはAPIからHTTP GETリクエストを作成し、BLOBをサービスにストリーミングします。
成分:
this.svc.getDownloadFile(fileID, fileName).subscribe(res => {
console.log(res);
});
}
サービス:
getDownloadFile(fileId: number, fileName: string): Observable<any> {
return this.http.get(this.downloadFileUrl + "/" + fileId, {
reportProgress: true,
observe: "events",
headers: this.getHeaders(),
responseType: "blob"
});
}
問題は、これがAPI呼び出しであるため、blobがXHRを介してストリーミングされ、Chromeの[ネットワーク]タブでダウンロードと進行状況を確認できることです。私が抱えている問題は、Chrome(または任意のブラウザー)でファイルをダウンロードするときに通常予想される、ある種のブラウザーダウンロード通知を受け取ることです。これは、応答全体が完了した後にのみ発生します。
たとえば、データベースに50MBのファイルがあります。ユーザーがリンクをクリックしてAngularアプリからファイルをダウンロードすると、コンポーネントがサービスを呼び出し、API呼び出しを実行して、DBからファイルを取得し、blob応答としてストリーミングします。Angularはこの応答を受け取り、50 MBをすべてダウンロードするまで待機してから、ダウンロードダイアログを表示します。
APIは、コンテンツの長さ、コンテンツタイプ、ファイル名などとともにContent Dispositionヘッダーを返します。私はこれを模倣するものを探して高低を検索しましたが、ブラウザーが通常どおりに自動的にダウンロードしないことを理解しています。リクエストはAngularを介してパイプ処理されており、ブラウザーはすべてのblobXHRを保存する必要があると自動的に想定しないためです。
https://www.npmjs.com/package/streamsaverを使用してみましたが、このパッケージは実際にはすでに保存されているファイルのみを処理し、APIからblobとして送信されたファイルは処理しません。
したがって、ここで同じ問題を抱えている人々のために、私がしたことは次のとおりです。
これは私の作業設定用であることに注意してください。暗号化されたBLOBを格納するDBがあります。これは、ファイルストリームを介してAngularアプリにBLOBを提供するAPIです。
暗号化されていないAPIを使用している場合は、@ Paceで上記のようなことをwindow.open(urlToFile)
またはで行うことができますwindow.location.href(urlToFile)
。
私のAPIはヘッダーのBearerトークンを介した承認を必要とするため、私が行ったことは、要求されているファイルIDとともにトークンをチェックするエンドポイントを作成することです。次に、APIはGUID(またはある種の一意のID)を作成し、GUIDとファイルIDを一緒にリストに保存します。リストは、有効期限とともにMemoryCacheに保存されます。
これが完了すると、GUIDが作成されたOk応答が返されます。私はセキュリティの専門家ではありませんが、次の理由でセキュリティが確保される可能性があると思いますが、これは完全な解決策ではないと確信しています。
GUIDはAngularアプリに戻り、GUIDが戻ってきた後、呼び出しを呼び出しwindow.location.href
て、GUIDとファイルIDを渡す別のエンドポイントに設定します。
このエンドポイントは認証を必要としないように構成されており、リストにあり、正しいGUIDが渡されたファイルのダウンロードのみを許可します。
たとえば、これは呼び出される私のサービスです。
getDownloadFile(fileId: number): Observable<any> {
return this.http
.get(this.downloadFileUrl + "/" + fileId, {
headers: this.getHeaders() //Attaches bearer token
})
.pipe(
tap(res => { //res = the GUID being returned from API
window.location.href =
this.downloadFileUrl + "/temp/" + fileId + "/" + res;
})
);
}
ご覧のとおり、認証されたエンドポイントを呼び出し、GUIDを取得し、GUIDとファイルIDを使用して、現在のブラウザウィンドウのURLを一時エンドポイントにすぐに設定します。これは、Content Dispositionが正しく設定された状態で戻ってくるファイルストリームまたはBLOBであるため、Angularアプリから移動せず、ダウンロードマネージャーからダウンロードを開始するだけであることに注意してください。
これは、ブラウザがストリーミングAPIエンドポイントからのダウンロードを通常どおり処理できるようにする唯一の方法です。
ほとんどの小さなファイルは、APIを介して非常に高速にダウンロードされるため、ダウンロードが最初に開始されたかどうかがわからないため、実際には問題ではありません。通常、ダウンロードは瞬く間に行われるためですが、大きなファイルの場合は、 XHRを介してAPI呼び出しを行うと、リクエストが終了してからBAMが完了するまで、ユーザーはファイルがダウンロードされていることを示しません。突然、ダウンロードに150MBのファイルが表示されるようになりました。これも優れた方法です。Angularアプリを終了しても、アプリで終了する通常のAPI XHRサブスクリプションとは異なり、ダウンロードが継続されるためです。また、BLOBを含むXHRリクエストをタップして進行状況を追跡する方法も見つけましたが、Angularアプリ内に独自のダウンロードマネージャーを作成する必要があり、ほとんどのユーザーが期待するブラウザーのデフォルトを使用しないでください。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加