Domanda

Sto lavorando per cercare di ottenere iOS 6 per utilizzare i post XMLHTTPRequest per caricare le immagini.Ciò funziona su browser web desktop e Android, ma con iOS 6 ricevo un errore sulla pagina che viene pubblicato su: "Richiedi il flusso del corpo esausto".(Utilizzo di IOS Simulator con Safari Web Inspector).

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.");
}
.

Quando si esegue questo su qualsiasi altro browser, il gestore ritorna correttamente e carica il file.Tuttavia, con iOS la pagina Ashx ha l'errore "Richiedi il flusso del corpo esausto".

Ecco uno screenshot dell'ispettore:

Richiedi il flusso del corpo esaurito

Qualche idea?

Aggiornamento: Questo problema si verifica solo quando l'autenticazione NTLM / Windows è abilitata per l'applicazione in IIS.Con forme o autenticazione anonima, il caricamento funziona bene.

Grazie,

John

È stato utile?

Soluzione

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

Tuttavia, con NTLM, otterrà una sfida 401 in risposta, e quindi dovrà inviare nuovamente il post con le informazioni di autenticazione.Dal momento che non resetta il flusso di file, non è possibile inviare nuovamente il file con il secondo post.Puoi vederlo nei registri IIS.

Per quanto ne so, non c'è modo particolarmente buono intorno ad esso.Sto cambiando la mia app mobile, in modo che utilizzi l'autenticazione del modulo.Direggio l'app mobile a un'app di accesso separato sullo stesso server, che è impostato per utilizzare l'autenticazione di Windows.L'app Login può quindi reindirizzare l'app principale con un cookie di autenticazione del modulo, e tutto va bene.

È necessario impostare il tasto macchina su entrambe le app nel file Web.config, in modo che entrambi stiano utilizzando gli stessi tasti per la crittografia e la convalida.

Il codice sull'app Login è 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
.

Altri suggerimenti

Ho risolto il problema non impostando la testina HTTP auto-definita Authenticate su iOS 7 e iOS 8. (all'inizio, il nostro servizio utilizza il valore auto-definito per la testa autenticata).E dopo la sfida viene gestita dal delegato, la richiesta avrà l'intestazione automatica "Authenticate: NTLMXXXX" automaticamente.E il posto e post funziona di nuovo.

Questo errore arriva su iOS ma puoi usare un approccio diverso Come cambiare la tua riga di codice in FormData in cui si aggiunge il file

var fd = new FormData();

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

Alla linea sottostante fondamentalmente non aggiungere il controllo del file ma utilizzare i dati di immagine BASE64

var reader = new FileReader();

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

reader.onload = function () {

    var base64DataImg = reader.result;            

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

}
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top