Pregunta

Estoy trabajando en tratar de obtener iOS 6 para usar las publicaciones XMLHTTPRequest para cargar imágenes.Esto funciona en los navegadores web de escritorio y Android, pero con iOS 6, estoy recibiendo un error en la página que se está publicando en: "Solicitud de flujo corporal agotado".(Uso del simulador de iOS con el inspector web de Safari).

Aquí está el código básico de la página:

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

Al hacer esto en cualquier otro navegador, el controlador regresa correctamente y carga el archivo.Sin embargo, con iOS, la página ASHX tiene el error "Solicitud de la corriente del cuerpo agotada".

Aquí hay una captura de pantalla del inspector:

Solicitud de flujo corporal agotado

¿Alguna idea?

Actualizar: Este problema solo ocurre cuando la autenticación NTLM / Windows está habilitada para la aplicación en IIS.Con formas o autenticación anónima, la carga funciona bien.

gracias,

john

¿Fue útil?

Solución

En iOS 6, Safari envía el archivo con la publicación inicial, incluido el archivo.Eso significa que la corriente de archivos está al final, o "agotado".

Sin embargo, con NTLM, obtendrá un desafío 401 en respuesta, y luego tendrá que reenviar la publicación con la información de autenticación.Como no restablece la transmisión de archivos, no puede enviar el archivo nuevamente con la segunda publicación.Puedes ver esto en los registros de IIS.

Por lo que sé, no hay una manera particularmente buena.Estoy cambiando mi aplicación móvil, para que use la autenticación del formulario.Dirija la aplicación móvil a una aplicación de inicio de sesión separada en el mismo servidor, que se configura para usar la autenticación de Windows.La aplicación de inicio de sesión puede volver a funcionar de nuevo a la aplicación principal con una cookie de autenticación de formulario, y todo está bien nuevamente.

Debe configurar la tecla de la máquina en ambas aplicaciones en el archivo web.config, de modo que ambos están usando las mismas teclas para el cifrado y la validación.

El código en la aplicación de inicio de sesión es tan simple como

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

Otros consejos

Resolví el problema al no establecer la cabeza de autenticación HTTP autodefinida en iOS 7 y iOS 8. (Al principio, nuestro servicio usa el valor autodefinido para la cabeza de autenticación).Y después del desafío que es manejado por el delegado, la solicitud tendrá automáticamente el encabezado "Autenticicate: NTLMXXX automáticamente" automáticamente.Y el puesto y el puesto funciona de nuevo.

Este error viene en iOS, pero puedes usar un enfoque diferente Como cambiar su línea de código en Formdata, donde agregue el archivo

var fd = new FormData();

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

a la siguiente línea, básicamente, no agregue el control de archivos, pero use los datos de imagen base64

var reader = new FileReader();

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

reader.onload = function () {

    var base64DataImg = reader.result;            

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

}

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top