Как получить имя файла, загруженного с помощью Angular $http?

Я написал код, который использует Angular $http для загрузки файла. Имя файла не указано в URL-адресе. 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.

Ответы

Ответ 1

Возможно, стоит упомянуть, что для получения имени файла из заголовков 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, '');
  }

Ответ 2

Если вы используете CORS, вам нужно добавить заголовки "Access-Control-Expose-Headers" в заголовки ответов на стороне сервера. Например: Access-Control-Expose-Headers: x-filename, x-something-else

Ответ 3

Используйте response.headers для получения заголовков HTTP-ответов:

$http.get(myUrl).then(function (response) {
    // extract filename from response.headers('Content-Disposition')
} 

Ответ 4

Возможно, вы уже нашли решение, но я отправлю этот ответ, если у кого-то еще есть эта проблема.

Добавьте эти параметры в функцию обратного вызова успеха из запроса $http:

    $http.get(myUrl).success(function (data, status, headers, config) {
        // extract filename from headers('Content-Disposition')
    });

Ответ 5

Если response.headers('Content-Disposition') возвращает значение null, используйте response.headers.**get**('Content-Disposition');.

Остальная часть фрагмента @andrew теперь отлично работает.

Ответ 6

Как и в некоторых из приведенных выше ответов, но с использованием базового RegEx, как я решил это вместо:

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;
}