2012-02-24 11 views
6

Ho una pagina Web di prova HTML5 test.html con un manifest di cache. La pagina web fa una richiesta Ajax allo stesso server, a una pagina web do_get_data.php elencata nella sezione NETWORK: nel manifest della cache.Chiamata di fail chiamata chiamata anche se la richiesta Ajax viene eseguita e il server restituisce 200 con dati

La richiesta viene eseguita da Firefox 10 e iPhone iOS 5 Safari (questo è registrato nello script PHP di servizio do_get_data.php). Firefox 10 chiama la funzione di callback success dopo 10 secondi, ovvero quando vengono restituiti i dati dal server. Tuttavia, il mio iPhone iOS 5 Safari chiama immediatamente la funzione di callback fail dopo aver avviato la richiesta e non chiama la funzione di callback success.

Per iPhone iOS 5 Safari, il textStatus è error e JSON.stringify(jqXHR) è {"readyState":0,"responseText":"","status":0,"statusText":"error"}.

La richiesta viene eseguita utilizzando il seguente codice nel test.html:

<script type="text/javascript"> 
    function test_ok(data) { 
     alert('Test OK, data: ' + JSON.stringify(data)); 
    } 
    function testFail(jqXHR, textStatus) { 
     alert(textStatus + ' | ' + JSON.stringify(jqXHR)); 
    } 
    function get_data(testurl) { 
     var senddata, request; 
     alert('Request for ' + testurl + ' started.'); 
     window.testid = new Date().getTime(); 
     senddata = { 
      background: true, 
      requestId: window.testid 
     }; 
     request = $.ajax({ 
      url: testurl, 
      cache: false, 
      type: "GET", 
      data: senddata, 
      success: test_ok 
     }); 
     request.fail(testFail); 
    } 
</script> 
<input type="button" onclick="get_data('do_get_data.php')" value="test sending" /> 

Per riferimento, do_get_data.php assomiglia a questo:

<?php 
    $id = md5(rand() . rand()); 
    trigger_error(implode("\t", array('start', $id, $_SERVER['REQUEST_URI'], $_SERVER['REMOTE_ADDR'], $_SERVER['USER_AGENT'])); 
    sleep(10); 
    header('Content-Type: application/json'); 
    $json = json_encode(array('msg'=>'Test was OK')); 
    trigger_error(implode("\t", array('echo', $id, $json)); 
    echo $json; 
?> 
+0

Cosa succede se si rimuove il sonno (10)? –

+0

E ho capito bene che hai un log che mostra richieste di successo da parte di Safari sul lato server? –

+0

@asaddude Anche se rimuovo sleep (10), la situazione è la stessa. Sì, il registro sul lato server mostra Safari. – AndersTornkvist

risposta

1

Che cosa succede se si cambia la $.ajax chiamata a

$.ajax({ 
    url: testurl, 
    cache: false, 
    type: "GET", 
    data: senddata 
}).then(
    function(result) { test_ok(result); }, 
    function(result) { testFail(result); } 
); 
+0

Grazie per la risposta. Sfortunatamente, questo non risolve il problema. Risulta comunque una richiesta, ma viene chiamato 'testFail()'. – AndersTornkvist

+0

Cosa succede se rimuovi l'intestazione Content-Type nel tuo codice PHP? Forse Safari ha un problema con questo. In tutto il codice AJAX che abbia mai scritto, non ho mai impostato un'intestazione Content-Type. Ho appena fatto eco al testo semplice. – SenorAmor

2

Mi è stato dato di capire che le cause del codice di stato 0 sono (1) il caricamento da file://, (2) la risorsa di rete irraggiungibile e (3) il criterio del dominio incrociato. Dato che carichi PHP, possiamo tranquillamente governare il numero 1 e dato che il tuo server registra Safari anche il numero 2, che ci lascia 3. 3. Tutto il codice sopra si trova nello stesso dominio? In caso contrario, utilizzare l'intestazione HTTP Access-Control-Allow-Origin nel PHP per consentire richieste tra domini diversi.

header('Access-Control-Allow-Origin: http://example.org') 

Inoltre, è necessario assicurarsi, il clic sull'ingresso pulsante esegue solo il onclick e non qualsiasi altro comportamento di default (qualunque essa sia sul iOS). Tornando false dal gestore onclick impedirebbe esso:

<input type="button" onclick="get_data('do_get_data.php'); return false" ... /> 

UPDATE:

Come ultima risorsa si può sempre semplicemente disabilitare la cache manifesta per spostare la sua attuazione forse buggy fuori strada.

+0

Grazie mille per la risposta. Mi piace il tuo ragionamento. In teoria, sono d'accordo che potrebbe trattarsi di un problema di politica interdominio. Tuttavia, è sullo stesso dominio. 'http: //' non è nemmeno usato per l'URL, ma 'do_get_data.php' senza alcun nome di dominio. C'è un buon modo per eseguire il debug di questo problema? Restituire false in realtà non ha cambiato nulla. – AndersTornkvist

+0

Sfortunatamente, le funzionalità di debugging sono molto scarse su iOS e sui dispositivi mobili in generale ... Quando facevo la mia ricerca, mi sono imbattuto in menzioni correlate, dove il percorso relativo era identificato come causa. Hai provato il percorso URL assoluto? E per chiarire: il problema persiste senza il manifest della cache? –

+0

L'utilizzo di un URL assoluto che include 'http: //' non ha risolto il problema. – AndersTornkvist

1

Non sono sicuro di come si esegue il sito in iOS, ma c'è stato un problema con le richieste jQuery e AJAX durante l'utilizzo di file manifesto: http://bugs.jquery.com/ticket/8412

Anche se si sta già che elenca le risorse che rientrano nella sezione Rete del manifesto, vorrei suggerire di provare l'altra soluzione elencata là:

jQuery.ajaxSetup({ 
    isLocal: true 
}); 
+0

Grazie per le nuove idee sul problema. Sembra che il biglietto restituisca effettivamente il contenuto corretto, il che non è il mio caso. La richiesta viene effettivamente eseguita dal vivo sul server. Ho provato con 'isLocal: true' ma sfortunatamente questo non ha risolto il problema. Lo stesso errore esiste. – AndersTornkvist

2

ho lottato con questo per un po 'e la risposta è stata nelle risposte rapporto bug:

uso

RETE: *

nella cache manifest per evitare la memorizzazione nella cache la richiesta AJAX troppo.

Problemi correlati