响应头与UTF-8附件文件名与撇号下载与错误的文件名在Chrome和Edge浏览器



当Chrome和Edge收到包含撇号的UTF-8文件名的标题时,似乎存在一个问题,即下载具有不正确文件名的文件。例如,调用这个URL: https://localhost:44328/Home/GetDocument?id=2

返回这个响应头:

附加项:附件;文件名* = utf - 8"供应商Notes.txt

将下载名为"供应商说明。txt"的文件;但是会下载一个名为" getdocument . html ">

这是已知的浏览器问题吗?有什么办法可以解决这个问题吗?

下面是一些示例MVC代码,您可以使用它们来重现问题:

HomeController.cs

using DownloadNameWithApostrophe.Models;
using System.Text;
using System.Web.Mvc;
namespace DownloadNameWithApostrophe.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new SampleViewModel());
}
public void GetDocument(int id)
{
if (!SampleViewModel.SampleData.ContainsKey(id))
{
return;
}
var attachmentString = "filename*=UTF-8''" + SampleViewModel.SampleData[id];
this.HttpContext.Response.Clear();
this.HttpContext.Response.AddHeader("Content-Disposition", "attachment; " + attachmentString);
this.HttpContext.Response.AddHeader("Contenty-type", "application/octet-stream");
var bytes = Encoding.ASCII.GetBytes("Hello World");            
this.HttpContext.Response.OutputStream.Write(bytes, 0, bytes.Length);
this.HttpContext.Response.Flush();
this.HttpContext.Response.End();
}       
}
}

SampleViewModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace DownloadNameWithApostrophe.Models
{
public class SampleViewModel
{
public static Dictionary<int, string> SampleData
{
get
{
var downloads = new Dictionary<int, string>();
downloads.Add(1, "Initial Estimate.txt");
downloads.Add(2, "Supplier's Notes.txt");
return downloads;
}
}
[Display(Name = "Available Downloads")]
public Dictionary<int, string> Downloads { get; set; }
public SampleViewModel()
{
Downloads = SampleData;
}

}
}

Index.cshtml

@model DownloadNameWithApostrophe.Models.SampleViewModel
@{
Layout = null;
}
<div class="row">
<div class="col-md-4">
<h2>Getting started</h2>
@Html.LabelFor(m => m.Downloads)
@foreach (var download in Model.Downloads)
{
<br />
<a href="@Url.RouteUrl(new {action="GetDocument", controller="Home"})?id=@download.Key">@download.Value</a>
}
</div>
</div>

这是因为Chromium实现了RFC 3986,其中'是一个保留字符,必须进行百分比编码。

您可以使用Uri.EscapeDataString()转义字符串:

var attachmentString = "filename*=UTF-8''" + Uri.EscapeDataString(SampleViewModel.SampleData[id]);

则文件名为"Supplier’s notes .txt";

相关内容

最新更新