2013-03-22 12 views
11

Vorrei inviare una richiesta di contenuto parziale da un oggetto XMLHttpRequest in javascript. Sto caricando un file binario di grandi dimensioni dal server, e preferisco lo streaming dal server in modo simile a come viene gestito il video html5.XMLHttpRequest 206 Contenuto parziale

Posso usare setRequestHeader per impostare l'intestazione Range. La Network Inspector di Chrome mostra che l'intestazione Range è stata impostata correttamente. Tuttavia, l'intestazione Accept-Encoding è impostata su "gzip, deflate" e Chrome non mi consente di impostare quell'intestazione (dagli standard W3C).

C'è un modo per forzare il server a rispondere con un contenuto parziale di 206 dall'oggetto XMLHttpRequest solo da javascript?

+1

Programmate/gestite anche il lato server o eseguite solo script sul lato client? – kay

+1

Preferirei mantenerlo lato client, anche se ho accesso al lato server. Sto codificando qualcosa che genera una pagina statica che potrebbe essere caricata su altri host, quindi preferirei non dover scherzare con il lato server ... – jamesshuang

risposta

8

Penso di aver capito perché la richiesta 206 non funzionava. Con la compressione gzip abilitata, l'intestazione dell'intervallo viene ignorata se i dati in uscita possono essere compressi con gzip.

Il file che stavo richiedendo era un file binario di grandi dimensioni, che nginx interpretava come con mimetype application/octet-stream. Questo è uno dei mimi che viene gzip. Se ho rinominato il file per avere un file .png, il mimetype image/png non è gzip, e quindi la richiesta di range funziona correttamente.

Questo è anche il motivo per cui l'impostazione dell'intestazione Accept-Encoding con curl sull'identità consente anche alla richiesta di intervallo di funzionare correttamente. Tuttavia, non posso cambiare quella intestazione da un XHR.

Soluzione: modificare la tabella mimetype sul server!

12

Questa gamma-request funziona bene per me: 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); 

si deve fare in modo che il server consente le richieste di intervallo, però. Puoi testarlo con arricciatura:

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

Hmm, è bizzarro. Sto anche inviando una richiesta a un server nginx. Curl funziona bene con il comando -r. Tuttavia, quando provo quel codice esatto nel browser, ottengo solo 200 risposte per questo grande flusso di ottetti (40 mb). Qualche indizio che cosa potrebbe causare questo? – jamesshuang

+0

Il mio violino funziona? Quindi, avvisa (206)? – kay

+1

La tua risposta violino 206. Copia il codice ed esegui sul mio server, dà 200. Quali variabili del server potrebbero influenzare questo? – jamesshuang