Поведение HTTP-ответа - PullRequest
       28

Поведение HTTP-ответа

2 голосов
/ 05 января 2011

У меня есть две очень похожие части кода ASP.NET, которые отправляют файл в ответ HTTP для клиента. Они должны заставить браузер предлагать сохранить файл. Первый работает, второй нет. Ответы HTTP, как видно из Fiddler, приведены ниже.

Рабочая:

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);
}

Ответы [ 4 ]

1 голос
/ 05 января 2011

Пробел в значении параметра filename может быть причиной этого.Попробуйте использовать синтаксис в кавычках :

Content-Disposition: attachment; filename="report\ 2.xlsx"

См. Также RFC 2183 .

0 голосов
/ 05 января 2011

Очевидно, это была не проблема с ответом, а проблема с запросом. Оба HTTP-ответа в OP действительны, но ссылка на странице, которая вызвала вторую, была внутри панели asp ajax (UpdatePanel). Я слишком долго смотрел на эту проблему и слишком мало знаю о протоколе HTTP, чтобы понять точную причину этого, но различия в заголовках запросов были в следующих полях:

Рабочая (вне панели ajax):

Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5

Не работает (внутри панели ajax):

X-Requested-With: XMLHttpRequest
X-MicrosoftAjax: Delta=true
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Cache-Control: no-cache
Accept: */*

Проблема исчезла после удаления ссылки с панели ajax. «Connection: Close» все еще находится в (теперь работающем) заголовке, так что, очевидно, это никак не связано с проблемой.

Спасибо за помощь!

0 голосов
/ 05 января 2011

Я на самом деле немного удивлен, что первый работает - я думал, что браузеры довольно требовательны к регистру HTTP-заголовков.

Попробуйте изменить заголовок «content-disposition» на «Content-Disposition».

0 голосов
/ 05 января 2011

Проблема здесь:

 Connection: Close

Многие браузеры - особенно для загрузки - используйте 100 и продолжайте читать заголовки и проверять длину содержимого. Второй не позволит браузеру сделать это.


(ДОПОЛНЕНО)

Это генерируется из-за этой строки:

 Response.Buffer = false;

Удалите его, и он должен работать как шарм!

...