2013-03-22 15 views
11

Chciałbym wysłać częściową prośbę o treść z obiektu XMLHttpRequest w javascript. Ładuję duży plik binarny z serwera i wolałbym go przesyłać strumieniowo z serwera, podobnie jak w przypadku obsługi wideo HTML5.XMLHttpRequest 206 Częściowa zawartość

Mogę użyć setRequestHeader do ustawienia nagłówka Range. Inspektor sieci w Chrome pokazuje, że nagłówek Zakres jest ustawiony pomyślnie. Jednak nagłówek Accept-Encoding jest ustawiony na "gzip, deflate", a Chrome nie pozwala mi ustawić tego nagłówka (ze standardów W3C).

Czy istnieje sposób zmuszenia serwera do odpowiedzi z częściową treścią 206 z obiektu XMLHttpRequest tylko z javascript?

+1

Czy programujesz/konserwujesz stronę serwera, czy też robisz tylko skrypty po stronie klienta? – kay

+1

Wolałbym zachować to po stronie klienta, chociaż mam dostęp do strony serwera. Koduję coś, co generuje statyczną stronę, którą można przesłać do innych hostów, więc wolałbym nie zadzierać po stronie serwera ... – jamesshuang

Odpowiedz

8

Chyba zorientowałem się, dlaczego żądanie 206 nie działa. Po włączeniu kompresji gzip nagłówek zakresu zostaje zignorowany, jeśli dane wychodzące mogą zostać zgrupowane gzip.

Żądany plik był dużym plikiem binarnym, który nginx został zinterpretowany jako mający mimetype application/octet-stream. Jest to jeden z typów MIME, który dostaje gzip. Jeśli zmieniłem nazwę pliku, aby miał typ pliku PNG, typ MIME image/png nie jest spakowany gzipem, a zatem żądanie zasięgu działa poprawnie.

To jest powód, dla którego ustawienie nagłówka Accept-Encoding z curl na tożsamość również pozwala na prawidłowe działanie żądania zasięgu. Jednak nie mogę zmienić tego nagłówka z XHR.

Rozwiązanie: Zmień tabelę typów na serwerze!

12

Ten zakres-prośba działa dobrze dla mnie: 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); 

Musisz upewnić się, że serwer pozwala żądania zasięgu, choć. Możesz przetestować to z lokami:

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

Hmm, to dziwne. Wydaje również żądanie do serwera nginx. Curl działa dobrze z poleceniem -r. Kiedy jednak wypróbuję ten dokładny kod w przeglądarce, otrzymuję odpowiedź 200 tylko dla tego dużego strumienia oktetów (40 mb). Jakieś wskazówki, które mogą być przyczyną tego? – jamesshuang

+0

Czy moje skrzypce działają? Czy to alarmuje (206)? – kay

+1

Twoja odpowiedź na skrzypce 206. Skopiuj kod i uruchom na moim własnym serwerze, daje 200. Jakie zmienne serwerowe mogłyby wpłynąć na to? – jamesshuang