Angular $ httpを使用してファイルをダウンロードするコードを記述しました。ファイルの名前はnotで指定されています。URLには一意の識別子が含まれていますアプリケーションの外部から取得されたファイル。
$http.get(myUrl)
が呼び出されると、すべてが正常に機能します。ファイルが取得され、コールバックハンドラでアクセスできますが、ファイルの名前を取得する方法がわかりません。 Fiddlerで生の応答をキャプチャすると、次のように表示されます。
_HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 54
Content-Type: application/octet-stream
Server: Microsoft-IIS/8.5
Access-Control-Allow-Origin: http://www.example.com/getFile/12345
Access-Control-Allow-Credentials: true
Content-Disposition: attachment; filename=testfile.txt
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 09 Oct 2015 20:25:49 GMT
Lorem ipsum dolar sit amet! The contents of my file!
_
上記から、サーバーが「Content-Disposition」でファイルの名前を送り返していることは明らかですが、Angularコールバック内でアクセスすることはできませんでした。ヘッダーからファイルの名前を取得するにはどうすればよいですか?
以下の回答に応じて編集します。 以前にresponse.headers()
を試したことに言及する必要がありました。 _Object {content-type: "application/octet-stream", cache-control: "private"}
_を返すため、何らかの理由でまだContent-Dispositionを取得できません。 response.headers('Content-Disposition')
はnull
を返します。
HTTPヘッダーからファイル名を取得するために、Content-Disposition
ヘッダーを抽出するだけでは十分ではないことを言及する価値があります。このヘッダー値からfilename
プロパティを取得する必要があります。
返されるヘッダー値の例:attachment; filename="myFileName.pdf"
。
以下の関数はfilename="myFileName.pdf"
を抽出し、次に"myFileName.pdf"
を抽出し、最後に余分な引用符を削除してmyFileName.pdf
を取得します。
以下のスニペットを使用できます。
function getFileNameFromHttpResponse(httpResponse) {
var contentDispositionHeader = httpResponse.headers('Content-Disposition');
var result = contentDispositionHeader.split(';')[1].trim().split('=')[1];
return result.replace(/"/g, '');
}
CORSを使用する場合、サーバー側の応答ヘッダーに「Access-Control-Expose-Headers」を追加する必要があります。例えば: Access-Control-Expose-Headers: x-filename, x-something-else
Web API:IHttpActionResult実装のExecuteAsync(...)メソッドに次のコード行を追加すると動作することがわかりました('response'は返されるHttpResponseMessageです):
response.Content.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
Angular:次に、angularのファイル名を次のように解決できました('response'は$ http.getから解決された約束です):
var contentDisposition = response.headers('Content-Disposition');
var filename = contentDisposition.split(';')[1].split('filename')[1].split('=')[1].trim();
つかいます response.headers
は、HTTP応答ヘッダーを取得します。
$http.get(myUrl).then(function (response) {
// extract filename from response.headers('Content-Disposition')
}
response.headers('Content-Disposition')
がnullを返す場合、response.headers.**get**('Content-Disposition');
を使用します。
@andrewの残りのスニペットは、今ではうまく機能します。
上記の答えのいくつかに似ていますが、基本的な正規表現を使用すると、代わりにそれを解決する方法です:
let fileName = parseFilenameFromContentDisposition(response.headers('Content-Disposition'));
function parseFilenameFromContentDisposition(contentDisposition) {
if (!contentDisposition) return null;
let matches = /filename="(.*?)"/g.exec(contentDisposition);
return matches && matches.length > 1 ? matches[1] : null;
}
すでに解決策を見つけているかもしれませんが、他の誰かがこの問題を抱えている場合は、この回答を投稿します。
$ httpリクエストの成功コールバック関数にこれらのパラメーターを追加します。
$http.get(myUrl).success(function (data, status, headers, config) {
// extract filename from headers('Content-Disposition')
});
success(function(data, status, headers, response,xhr) {
console.log(headers('Content-Disposition'));
}