下载后在客户端获取文件名。CORS

Ste*_*pUp 1 c# cors asp.net-core asp.net-core-1.0 angular

我已经设法从服务器端下载文件:

[EnableCors("AllowAll")]
[HttpGet("{id}", Name = "Get")]
public IActionResult Get(int id)
{
    var fileName = "Far30b4949.x86.20170503.zip"; //*** Creation file name
    var filepath = _hostingEnvironment.WebRootPath;
    byte[] fileBytes = System.IO.File.ReadAllBytes(_hostingEnvironment.WebRootPath + 
                          @"\" + fileName);
    return File(fileBytes, "application/zip", fileName); //*** Sending file name
}
Run Code Online (Sandbox Code Playgroud)

和客户端代码:

public downloadFile() {       
    let projectAUrl = 'http://localhost:49591/api/file/5';
    return this.http.get(projectAUrl, {responseType: ResponseContentType.Blob})
        .map((response) => {
            return new Blob([response.blob()], {type:'application/zip'})
        })
        .subscribe((res)=> {
            saveAs(res, "Name does not come here")//there is no file name, 
            //but there is a file type("application/zip")
        });
}
Run Code Online (Sandbox Code Playgroud)

CORS设置:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();
    //Add CORS support to the service
    services.AddCors(options=> options.AddPolicy("AllowAll", p => 
            p.AllowAnyOrigin()
             .AllowAnyHeader()
             .AllowAnyMethod()
             .AllowCredentials()));
}
Run Code Online (Sandbox Code Playgroud)

我在客户端拥有的功能: 在此处输入图片说明

但是,从服务器端下载文件时,客户端没有文件名。如何获取文件名?

更新:

我已删除了对的呼叫map()

public downloadFile() {       
    let projectAUrl = 'http://localhost:49591/api/file/5';
    return this.http.get(projectAUrl, {responseType: ResponseContentType.Blob})            
        .subscribe((res)=> {
            saveAs(res, "Name does not come here")//there is no file name, 
            //but there is a file type("application/zip")
        });
}
Run Code Online (Sandbox Code Playgroud)

但是,没有文件名:

在此处输入图片说明

更新2:

如果我对CORS使用以下策略:

services.AddCors(options => options.AddPolicy("ExposeResponseHeaders", 
    p =>
    { 
        p.WithOrigins("http://localhost:49591")
         .WithExposedHeaders("Content-Disposition");
    }));
Run Code Online (Sandbox Code Playgroud)

然后我得到以下错误:

XMLHttpRequest cannot load http://localhost:49591/api/file/5. No 'Access-
Control-Allow-Origin' header is present on the requested resource. Origin 
'http://localhost:3000' is therefore not allowed access. The response had 
HTTP status code 500.
Run Code Online (Sandbox Code Playgroud)

Fed*_*uma 6

只需删除对lambda函数中的调用map并提取blob数据和文件名即可subscribe

public downloadFile() {       
    let projectAUrl = 'http://localhost:49591/api/file/5';
    return this.http.get(projectAUrl, {responseType: ResponseContentType.Blob})
        .subscribe((response)=> {
            var blob = new Blob([response.blob()], {type:'application/zip'});
            var header = response.headers.get('Content-Disposition');
            var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
            var matches = filenameRegex.exec(header);
            if (matches != null && matches[1]) { 
                fileName = matches[1].replace(/['"]/g, '');
            }
            saveAs(blob, fileName);
        });
}
Run Code Online (Sandbox Code Playgroud)

Content-Disposition标头解析来自: 如何从内容处置中获取文件名

关于您的CORS配置

您可以尝试使用以下策略(添加您可能会发现浏览器未读取的任何其他标头):

services.AddCors(options => options.AddPolicy("ExposeResponseHeaders", 
    p =>
    { 
        p.WithOrigins("http://localhost:3000") // single origin THIS MUST BE THE SAME OF YOUR ANGULAR APPLICATION (not your ASP.NET Core app address)
         .AllowAnyMethod() // any method
         .AllowAnyHeader() // any header is *allowed*
         .AllowCredentials() // credentials allowed
         .WithExposedHeaders("Content-Disposition"); // content-disposition is *exposed* (and allowed because of AllowAnyHeader)
    }));
Run Code Online (Sandbox Code Playgroud)


小智 6

尝试在返回结果之前在控制器中显式添加“Access-Control-Expose-Headers”。
例如:

[HttpPost("export/excel")]
public async Task<IActionResult> ExportToExcel([FromBody] ExportReportRequest request)
{
    ...
    (byte[] fileContents, string fileName) = await this.salaryService.ExportReportToExcelAsync(request, userId).ConfigureAwait(false);
    this.Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
    return this.File(fileContents, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
}
Run Code Online (Sandbox Code Playgroud)