IOS 6 (iPhone / iPad) Carga de imagen "Solicitar flujo de cuerpo agotado" con NTLM / Autenticación de Windows
-
12-12-2019 - |
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:
¿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
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,', '');
}