【问题标题】:how to read content-disposition headers from server response angular 2如何从服务器响应角度 2 中读取内容处置标头
【发布时间】:2022-02-02 21:22:09
【问题描述】:

我无法找到如何从 Angular 2 文档中的内容配置中读取文件名。有人可以指导从服务器读取标头 2content headers

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    使用新的 Angular Http,可以在服务代码中尝试以下操作。

      downloadLink(): Observable<HttpResponse<Blob>> {
        return this.http.get<Blob>(this.someURL, {
          observe: 'response',
          responseType: 'blob' as 'json'
        });
      }
    

    并将上面的用作

     this.someService
      .downloadLink()
      .subscribe(
        (resp: HttpResponse<Blob>) => {
          console.log(resp.headers.get('content-disposition'));
          data = resp.body
        });
    

    此外,在服务器端,需要设置以下标头作为响应。 'Access-Control-Expose-Headers': 'Content-Disposition'

    就像在 Java Spring Boot 中一样,也可以使用

        final HttpHeaders headers = new HttpHeaders();
        headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=1.xlsx");
        headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
    

    【讨论】:

    • 谢谢尼哈尔!这对我有帮助。我没有公开标题作为回应。
    • 添加 observe: 'response' 会使我的 zip 文件损坏
    • 添加响应类型破坏数据
    • 也添加到服务器端,这是我在标题键["cache-control", "content-length", "content-type", "expires", "pragma"] 中得到的,但在浏览器中ACCESS_CONTROL_EXPOSE_HEADERS: CONTENT_DISPOSITIONCONTENT_DISPOSITION: abc.xml 出现在我的响应标题中
    • 对于 .NET Core app.Use((ctx, next) =&gt; { ctx.Response.Headers.Add("Access-Control-Expose-Headers", "*");
    【解决方案2】:

    对于那些抱怨最佳解决方案不起作用,并且只有内容类型在标题中的人,您需要在服务器端设置 'Access-Control-Expose-Headers': 'Content-Disposition'。我使用的是asp.net core,那么我必须做到以下几点。

    app.UseCors(builder =>
                    builder.WithOrigins(originsAllowed.ToArray())
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .WithExposedHeaders("Content-Disposition")
    

    【讨论】:

      【解决方案3】:

      你可以在这里试试这种代码。

      注意:不要使用地图

      this.http.post(URL, DATA)
        .subscribe((res) => {
           var headers = res.headers;
           console.log(headers); //<--- Check log for content disposition
           var contentDisposition = headers.get('content-disposition');
      });
      

      【讨论】:

      • 感谢@Partha Sarathi Ghosh 的精彩回复,它似乎也可以使用 map 方法
      • 如何达到与Promise相同的效果?
      • 对我不起作用。标题中只有内容类型
      • 也不适合我。标题中只有内容类型
      • res.headers 对我来说是未定义的,但我可以在 header 的 content-disposition 中找到文件名
      【解决方案4】:

      在 Angular 中,我们可以读取 文件名,如下所示,

        this.http.post(URL, DATA).subscribe(
              (res) => {
                  var contentDisposition = res.headers.get('content-disposition');
                  var filename = contentDisposition.split(';')[1].split('filename')[1].split('=')[1].trim();
                  console.log(filename);
              });
      

      但最主要的是我们需要在API中指定Access-Control-Expose-Header,如下图,

      注意:最后一行是必填项

      FileInfo file = new FileInfo(FILEPATH);
      
      HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
      response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
      {
          FileName = file.Name
      };
      response.Content.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
      

      【讨论】:

      • 请注意,如果文件名中包含自定义字符,则上面的代码缺少对出现的引号的替换。您应该在 .trim() 之后添加 .replace(/\"/g, '')
      • 这仅在文件名是处置字符串中的 [1] 元素时才有效。
      【解决方案5】:

      使用 Angular 9 和 Expresss

      需要在 Express 中允许此标头

      res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
      

      角度

      this.http.get(url, { observe: 'response', responseType: 'blob' as 'json' })
      .subscribe((res: any) => {
          console.log(res.headers.get('content-disposition'));
      });
      

      【讨论】:

      • 对于 .NET Core app.Use((ctx, next) =&gt; { ctx.Response.Headers.Add("Access-Control-Expose-Headers", "*");
      【解决方案6】:

      在 Angular 7 中,投票的方法不起作用,您需要这样做:

      const responseHeaderFilename = response.headers.get('content-disposition');
      

      更多详情请查看 Angular 官方文档:https://angular.io/guide/http#reading-the-full-response

      并确保“内容处置”在@mslugx 答案中公开

      【讨论】:

        【解决方案7】:

        从响应头中获取文件名。

        (data)=>{  //the 'data' is response of file data with responseType: ResponseContentType.Blob.
            let filename = data.headers.get('content-disposition').split(';')[1].split('=')[1].replace(/\"/g, '')
        }
        

        【讨论】:

        • 这仅在文件名是处置字符串中的 [1] 元素时才有效。
        • 替代方案:decodeURI(response.headers.get('content-disposition')?.match(/(?&lt;=filename(?:=|\*=(?:[\w\-]+'')))["']?(?&lt;filename&gt;[^"';\n]+)["']?/g)?.pop()?.replace(/\"/g, ''))
        【解决方案8】:

        CORS 请求仅公开 6 个标头:

        • 缓存控制
        • 内容-语言
        • 内容类型过期
        • Last-Modified 和 Pragma。

        为了通过 CORS 请求访问自定义标头,服务器必须明确将它们列入白名单。这可以通过发送响应头来完成:Access-Control-Expose-Headers

        Java : addExposedHeader https://docs.spring.io/spring-framework/docs/4.2.x/javadoc-api/org/springframework/web/cors/CorsConfiguration.html

        .NET CORE : WithExposedHeaders https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-6.0

        Express JS : exposedHeaders https://expressjs.com/en/resources/middleware/cors.html

        【讨论】:

          猜你喜欢
          • 2019-03-14
          • 1970-01-01
          • 1970-01-01
          • 2016-05-30
          • 1970-01-01
          • 1970-01-01
          • 2019-04-27
          • 2017-06-23
          • 2016-06-04
          相关资源
          最近更新 更多