7

Sto lavorando per cercare di ottenere iOS 6 da utilizzare POST XMLHttpRequest per caricare le immagini. Funziona con i browser Web desktop e Android, ma con iOS 6 ricevo un errore nella pagina che viene pubblicata su: "Richiedi Body Stream Exhausted". (Utilizzo di iOS Simulator con Safari Web Inspector).iOS 6 (iPhone/iPad) l'immagine Caricare "Richiesta corpo flusso Esausto" con NTLM/autenticazione di Windows

Ecco il codice di base della pagina:

function fileSelected() { 
    var file = document.getElementById('fileToUpload').files[0]; 
    if (file) { 
     var fileSize = 0; 
     if (file.size > 1024 * 1024) 
      fileSize = (Math.round(file.size * 100/(1024 * 1024))/100).toString() + 'MB'; 
     else 
      fileSize = (Math.round(file.size * 100/1024)/100).toString() + 'KB'; 
     document.getElementById('fileName').innerHTML = 'Name: ' + file.name; 
     document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize; 
     document.getElementById('fileType').innerHTML = 'Type: ' + file.type; 
    } 
} 
function uploadFile() { 
    var fd = new FormData(); 
    fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]); 
    var xhr = new XMLHttpRequest(); 
    xhr.upload.addEventListener("progress", uploadProgress, false); 
    xhr.addEventListener("load", uploadComplete, false); 
    xhr.addEventListener("error", uploadFailed, false); 
    xhr.addEventListener("abort", uploadCanceled, false); 
    xhr.open("POST", "/UploadHandler.ashx"); 
    xhr.send(fd); 
} 
function uploadProgress(evt) { 
    if (evt.lengthComputable) { 
     var percentComplete = Math.round(evt.loaded * 100/evt.total); 
     document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%'; 
     document.getElementById('prog').value = percentComplete; 
    } 
    else { 
     document.getElementById('progressNumber').innerHTML = 'unable to compute'; 
    } 
} 
function uploadComplete(evt) { 
    /* This event is raised when the server send back a response */ 
    alert(evt.target.responseText); 
} 
function uploadFailed(evt) { 
    alert("There was an error attempting to upload the file."); 
} 
function uploadCanceled(evt) { 
    alert("The upload has been canceled by the user or the browser dropped the connection."); 
} 

Nel fare questo su qualsiasi altro browser, il conduttore ritorna correttamente e carica il file. Tuttavia, con iOS la pagina ashx ha l'errore "richiesta body stream esaurito".

Ecco uno screenshot della finestra di ispezione:

Request Body Stream Exhausted

Tutte le idee?

UPDATE: Questo problema si verifica solo quando l'autenticazione NTLM/Windows è abilitata per l'applicazione in IIS. Con i moduli o l'autenticazione anonima, il caricamento funziona correttamente.

Grazie,

John

risposta

5

In iOS 6, Safari invia il file con il post iniziale, incluso il file. Ciò significa che il flusso di file è alla fine o "esaurito".

Tuttavia, con NTLM, otterrà una sfida 401 in risposta, e poi di inviare nuovamente il post con le informazioni di autenticazione. Poiché non ripristina il flusso di file, non è in grado di inviare di nuovo il file con il secondo post. Puoi vederlo nei registri di IIS.

Per quanto ne so, non c'è è particolarmente buon modo intorno ad esso. Sto cambiando la mia app mobile, in modo che utilizzi l'autenticazione della forma. Dirigo l'app mobile a un'app di accesso separata sullo stesso server, che è impostata per utilizzare l'autenticazione di Windows. L'app di accesso può quindi reindirizzare nuovamente all'app principale con un cookie di autenticazione del modulo e tutto va di nuovo bene.

è necessario impostare la chiave del computer su entrambe le applicazioni nel file web.config, in modo che entrambi utilizzano le stesse chiavi per la crittografia e la convalida.

Il codice sul app di accesso è semplice come

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _ 
Handles Me.Load 
    With HttpContext.Current.User.Identity 
     If .IsAuthenticated Then 
      Dim sUser As String = .Name.ToLower.Trim 
      FormsAuthentication.RedirectFromLoginPage(s, False) 
     End If 
    End With 
End Sub 
+2

che è davvero quello che ho osservato anche.La tua soluzione è interessante. Per il momento (ho inviato un bug ad Apple per vedere se potrebbero ripararlo), ho effettivamente il caricamento del file in un iframe non autenticato che carica un file nella cartella temporanea ASP.NET e restituisce un token che la pagina autenticata viene quindi utilizzata come riferimento quando si recupera il file dalla cartella temporanea. –

+0

C'è una soluzione? Forse usando WCF, o forse usando qualche altra tecnica? Sono su SharePoint e l'autenticazione di Windows è un requisito. – harsimranb

0

ho risolto il problema, non impostare l'HTTP auto-definita Autentica testa su iOS 7 e iOS 8. (In un primo momento, utilizzare il nostro servizio valore auto-definito per l'Authenticate Head). E dopo che la sfida è stata gestita dal delegato, la richiesta avrà automaticamente l'intestazione "Autentica: NTLMxxx automaticamente". E Put and POST funziona di nuovo.

0

Questo errore Viene su IOS ma è possibile utilizzare approccio diverso come modificare la riga di codice in cui si formdata aggiungendo il file

var fd = new FormData(); 

fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]); 

alla linea in basso in fondo non aggiungere il controllo dei file ma utilizzare il i dati delle immagini base64

var reader = new FileReader(); 

reader.readAsDataURL(opmlFile.files[0]); 

reader.onload = function() { 

    var base64DataImg = reader.result;    

    base64DataImg = base64DataImg.replace('data:'imagetype';base64,', '');  

}