HTTP 响应行为
我有两段非常相似的 ASP.NET 代码,它们将 HTTP 响应中的文件发送到客户端。它们应该使浏览器提示保存文件。第一个有效,第二个无效。 Fiddler 中看到的 HTTP 响应如下。
工作:
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 228108
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
content-disposition: attachment; filename=Report.xlsx
Date: Wed, 05 Jan 2011 12:17:48 GMT
<binary data>
不工作:
HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 05 Jan 2011 12:19:21 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 228080
content-disposition: attachment; filename=report 2.xlsx
Cache-Control: private
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Connection: Close
<binary data>
当 Fiddler 中看到第一个时,浏览器会正确提示保存文件。当在 Fiddler 中看到第二个时,浏览器中没有发生任何可观察到的情况。 Chrome 和 Firefox 中的行为相同。
知道为什么会发生这种情况吗?
编辑:生成第二个响应的 ASP.NET 代码
Response.Buffer = false;
Response.ContentType = @"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AppendHeader("content-length", genstream.Length.ToString());
Response.AppendHeader("Content-Disposition", string.Format("attachment; filename={0}.xlsx", filename));
byte[] buffer = new byte[1024];
genstream.Position = 0;
int n;
while ((n = genstream.Read(buffer, 0, 1024) ) > 0)
{
Response.OutputStream.Write(buffer, 0, n);
}
I have two very similar pieces of ASP.NET code that send a file in an HTTP Reponse to the client. They should cause the browser to prompt to save the file. The first one works, the second one doesn't. The HTTP responses as seen in Fiddler are below.
Working:
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 228108
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
content-disposition: attachment; filename=Report.xlsx
Date: Wed, 05 Jan 2011 12:17:48 GMT
<binary data>
Not working:
HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Wed, 05 Jan 2011 12:19:21 GMT
X-AspNet-Version: 4.0.30319
Content-Length: 228080
content-disposition: attachment; filename=report 2.xlsx
Cache-Control: private
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Connection: Close
<binary data>
When the first one is seen in Fiddler the browser correctly prompts to save the file. When the second one is seen in Fiddler, nothing observable happens in the browser. Same behaviour in both chrome and firefox.
Any idea why this is happening?
EDIT: ASP.NET code that produces the second response
Response.Buffer = false;
Response.ContentType = @"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AppendHeader("content-length", genstream.Length.ToString());
Response.AppendHeader("Content-Disposition", string.Format("attachment; filename={0}.xlsx", filename));
byte[] buffer = new byte[1024];
genstream.Position = 0;
int n;
while ((n = genstream.Read(buffer, 0, 1024) ) > 0)
{
Response.OutputStream.Write(buffer, 0, n);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
filename 参数值中的空格可能会导致此问题。尝试使用引用字符串语法 相反:
另请参阅 RFC 2183。
The space in the filename parameter value might cause this. Try the quoted-string syntax instead:
See also RFC 2183.
实际上,我对第一个方法的工作感到有点惊讶 - 我认为浏览器对 HTTP 标头中的大小写非常挑剔。
尝试将“content-disposition”标题更改为“Content-Disposition”。
I'm actually a little surprised the first one is working - I thought browsers were pretty picky about case in HTTP headers.
Try changing the "content-disposition" header to "Content-Disposition".
问题出在这里:
许多浏览器 - 特别是下载 - 使用 100-and-continue 来读取标题并检查内容的长度。第二个不允许浏览器这样做。
(更新)
这是由于这一行而生成的:
删除它,它应该可以作为一个魅力!
Problem is here:
A lot of browsers - especially for downloads - use 100-and-continue to read the headers and check the length of the content. The second will not allow the browser to do that.
(UPDATE)
This is generated because of this line:
Remove it and it should work as a charm!
显然这不是响应的问题,而是请求的问题。 OP 中的两个 HTTP 响应都是有效的,但生成第二个响应的页面上的链接位于 asp ajax 面板 (UpdatePanel) 内。我已经盯着这个问题太久了,对 HTTP 协议知之甚少,无法调查其确切原因,但请求标头的差异是这些字段:
工作(ajax 面板外部):
不工作(ajax 面板内部) ):
从 ajax 面板中删除链接后,问题现在消失了。 “连接:关闭”仍然在(现在工作)标题中,因此这显然与问题无关。
感谢您的帮助!
Apparently it wasn't a problem with the response but a problem with the request. Both the HTTP responses in the OP are valid, but the link on the page that produced the second one was inside an asp ajax panel (UpdatePanel). I've been staring at this problem for too long and know too little about HTTP protocol to look into the exact cause of it but the differences in the request headers were these fields:
Working (outside ajax panel):
Not working (inside ajax panel):
Problem is now gone after removing the link from the ajax panel. "Connection: Close" is still in the (now working) header so that was obviously nothing to do with the problem.
Thanks for the help!