2013-03-22 3 views
11

Я хотел бы предоставить частичный запрос контента из объекта XMLHttpRequest в javascript. Я загружаю большой двоичный файл с сервера, и я предпочитаю передавать его с сервера, подобно тому, как обрабатывается видео html5.XMLHttpRequest 206 Частичное содержимое

Я могу использовать setRequestHeader для установки заголовка Range. Инспектор сети в Chrome показывает, что заголовок Range успешно установлен. Однако заголовок Accept-Encoding имеет значение «gzip, deflate», и Chrome не позволит мне установить этот заголовок (из стандартов W3C).

Есть ли способ заставить сервер отвечать частичным содержимым 206 из объекта XMLHttpRequest только из javascript?

+1

Вы программируете/поддерживаете серверную сторону, или выполняете только скрипты на стороне клиента? – kay

+1

Я бы предпочел оставить его на стороне клиента, хотя у меня есть доступ к серверной стороне. Я кодирую что-то, что генерирует статическую страницу, которая может быть загружена на другие хосты, поэтому мне бы не пришлось возиться с серверной стороной ... – jamesshuang

ответ

8

Я думаю, что я понял, почему запрос 206 не работал. С включенным сжатием gzip заголовок диапазона игнорируется, если исходящие данные могут быть сжаты.

Файл, который я запрашивал, был большим двоичным файлом, который nginx интерпретировал как имеющее приложение mimetype/октет-поток. Это один из mimetypes, который получает gzip. Если я переименовал файл в файл типа .png, то mimetype изображения/png не был бы gzipped, и, следовательно, запрос диапазона работает правильно.

Именно поэтому установка заголовка Accept-Encoding с помощью curl to identity также позволяет заданию диапазона работать нормально. Однако я не могу изменить этот заголовок из XHR.

Решение: измените таблицу mimetype на сервере!

12

Этот диапазон-запрос отлично работает для меня: http://jsfiddle.net/QFdU4/

var xhr = new XMLHttpRequest; 

xhr.onreadystatechange = function() { 
    if (xhr.readyState != 4) { 
    return; 
    } 
    alert(xhr.status); 
}; 

xhr.open('GET', 'http://fiddle.jshell.net/img/logo.png', true); 
xhr.setRequestHeader('Range', 'bytes=100-200'); // the bytes (incl.) you request 
xhr.send(null); 

Вы должны убедиться, что сервер разрешает запросы диапазона, хотя. Вы можете проверить его с помощью завитка:

$ curl -v -r 100-200 http://example.com/movie.mkv > /dev/null 
+2

Хм, это странно. Я также выдаю запрос на сервер nginx. Curl отлично работает с командой -r. Однако, когда я пытаюсь использовать этот точный код в браузере, я получаю только 200 ответов для этого большого потока октетов (40 мб). Какие-нибудь подсказки, что может быть причиной этого? – jamesshuang

+0

Работает ли моя скрипка? Итак, это предупреждение (206)? – kay

+1

Ответ на скрипку 206. Скопируйте код и запустите на моем собственном сервере, укажите 200. Какие серверные переменные могут повлиять на это? – jamesshuang