如何获取使用Angular $ http下载的文件的名称?

Dan*_*don 26 blob http-headers angularjs

我编写了使用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!
Run Code Online (Sandbox Code Playgroud)

从上面可以看出,服务器显然是在"Content-Disposition"中发回文件的名称,但我还没有找到在Angular回调中访问它的方法.如何从标题中获取文件的名称?

编辑以回答以下答案: 我之前应该提到我已经尝试过response.headers().它返回Object {content-type: "application/octet-stream", cache-control: "private"},所以我仍然没有得到Content-Disposition因为某些原因. response.headers('Content-Disposition')回报null.

Mat*_*att 37

值得一提的是,为了从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, '');
  }
Run Code Online (Sandbox Code Playgroud)

  • 您可能需要调整 @andrew 提供的函数的第一行,具体取决于您的 Angular 版本。`var contentDispositionHeader = httpResponse.headers.get('Content-Disposition')` (2认同)

Vla*_*mir 16

如果使用CORS,则需要在服务器端的响应头中添加"Access-Control-Expose-Headers".例如:Access-Control-Expose-Headers: x-filename, x-something-else

  • 你部分是真的.对于CORS,服务器必须将头发送为"Access-Control-Expose-Headers:Content-Disposition". (2认同)

Phi*_*hil 14

Web API:我发现将以下代码行添加到我的IHttpActionResult实现的ExecuteAsync(...)方法中('response'是要返回的HttpResponseMessage):

response.Content.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
Run Code Online (Sandbox Code Playgroud)

Angular:我当时能够以角度解析文件名,如下所示('response'是来自$ http.get的解析后的承诺):

var contentDisposition = response.headers('Content-Disposition');
var filename = contentDisposition.split(';')[1].split('filename')[1].split('=')[1].trim();
Run Code Online (Sandbox Code Playgroud)


Pat*_*cio 7

与上述某些答案类似,但是我使用基本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;
}
Run Code Online (Sandbox Code Playgroud)

  • 实际上,这要优于其他答案,因为其他答案取决于文件名是配置标头的第二个标记。如果不是由于某种原因,那么他们将返回错误的数据。 (2认同)

Mic*_*zos 5

使用response.headers获得HTTP响应头:

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

  • 实际上,您必须使用`Access-Control-Expose-Headers:Content-Disposition`来显示标题.这假设您可以控制服务器端响应... (4认同)

Hec*_*tor 5

// 服务

downloadFile(params: any): Observable<HttpResponse<any>> {

    const url = `https://yoururl....etc`;


    return this.http.post<HttpResponse<any>>(
      url,
      params,
      {
        responseType: 'blob' as 'json',
        observe: 'response' as 'body'
      })
      .pipe(
        catchError(err => throwError(err))
      );
  }
Run Code Online (Sandbox Code Playgroud)

// 成分

import * as FileSaver from 'file-saver';

... some code

  download(param: any) {
    this.service.downloadFile(param).pipe(
    ).subscribe({
      next: (response: any) => {

        let fileName = 'file';
        const contentDisposition = response.headers.get('Content-Disposition');
        if (contentDisposition) {
          const fileNameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
          const matches = fileNameRegex.exec(contentDisposition);
          if (matches != null && matches[1]) {
            fileName = matches[1].replace(/['"]/g, '');
          }
        }

        const fileContent = response.body;

        FileSaver.saveAs(fileContent, fileName);

      },
      error: (error) => {

        console.log({error});

      }
    });
  }
Run Code Online (Sandbox Code Playgroud)

享受