4

How Can I read Response Header (Content-Disposition)? Please share resolution.

When I check at either Postman or Google Chrome Network tab, I can see 'Content-Disposition' at the response headers section for the HTTP call, but NOT able to read the header parameter at Angular Code.

// Node - Server JS
app.get('/download', function (req, res) {
  var file = __dirname + '/db.json';
  res.set({
    'Content-Type': 'text/plain',
    'Content-Disposition': 'attachment; filename=' + req.body.filename
  })
  res.download(file); // Set disposition and send it.
});


// Angular5 Code
 saveFile() {
    const headers = new Headers();
    headers.append('Accept', 'text/plain');
    this.http.get('http://localhost:8090/download', { headers: headers })
      .subscribe(
        (response => this.saveToFileSystem(response))
      );
  }

  private saveToFileSystem(response) {
    const contentDispositionHeader: string = response.headers.get('Content-Disposition'); // <== Getting error here, Not able to read Response Headers
    const parts: string[] = contentDispositionHeader.split(';');
    const filename = parts[1].split('=')[1];
    const blob = new Blob([response._body], { type: 'text/plain' });
    saveAs(blob, filename);
  }

4 Answers 4

6

I have found the solution to this issue. As per Access-Control-Expose-Headers, only default headers would be exposed.

In order to expose 'Content-Disposition', we need to set 'Access-Control-Expose-Headers' header property to either '*' (allow all) or 'Content-Disposition'.

// Node - Server JS
app.get('/download', function (req, res) {
var file = __dirname + '/db.json';
res.set({
  'Content-Type': 'text/plain',
  'Content-Disposition': 'attachment; filename=' + req.body.filename,
  'Access-Control-Expose-Headers': 'Content-Disposition' // <== ** Solution **
})
res.download(file); // Set disposition and send it.
});
Sign up to request clarification or add additional context in comments.

Comments

2

It is not the problem with Angular, is the problem with CORS.

If the server does not explicitly allow your code to read the headers, the browser don't allow to read them. In the server you must add Access-Control-Expose-Headers in the response.

In the response it will be like Access-Control-Expose-Headers:<header_name>,

In asp.net core it can be added while setting up CORS in ConfigureServices method in startup.cs

enter image description here

Comments

1

Firstly you need to allow your server to expose these headers. Note that it will show in you browser network tab, regardless if you have these settings. This makes it 'available'.

With C# it would look something like this:

services.AddCors(options => {
  options.AddPolicy(AllowSpecificOrigins,
  builder => {
    builder
      .WithOrigins("http://localhost:4200")
      .AllowAnyHeader()
      .AllowAnyMethod()
      .WithExposedHeaders("Content-Disposition", "downloadFileName");
  });
});

When you send your API request to the server ensure that you include the "observe" in you return. See below:

getFile(path: string): Observable<any> {
  // Create headers
  let headers = new HttpHeaders();
  // Create and return request
  return this.http.get<Blob>(
    `${environment.api_url}${path}`,
    { headers, observe: 'response', responseType: 'blob' as 'json' }
  ).pipe();
}

Then in your response of your angular on your subscribe you can access your filename like this (the subscribe method is not complete it attaches to a pipe function)

.....
.subscribe((response: HttpResponse<Blob>) => {
  const fileName = response.headers.get('content-disposition')
    .split(';')[1]
    .split('filename')[1]
    .split('=')[1]
    .trim();
});

Comments

0

this solution help me to get the Content-Disposition from response header.

(data)=>{  //the 'data' is response of file data with responseType: ResponseContentType.Blob.
    let contentDisposition = data.headers.get('content-disposition');
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.