iOS 6(iPhone / iPad)图片上传“Request Body Stream Exhausted”使用NTLM / Windows身份验证 [英] iOS 6 (iPhone/iPad) Image Upload "Request Body Stream Exhausted" with NTLM/Windows Authentication
问题描述
我正在努力让iOS 6使用XMLHttpRequest POST来上传图片。这适用于桌面和Android Web浏览器,但是对于iOS 6,我在发布到的页面上收到错误:请求正文流用尽。 (将iOS模拟器与Safari Web Inspector一起使用)。
I am working on trying to get iOS 6 to use XMLHttpRequest POSTs to upload images. This works on desktop and Android web browsers, but with iOS 6 I am getting an error on the page being posted to: "Request Body Stream Exhausted". (Using iOS Simulator with the Safari Web Inspector).
以下是该页面的基本代码:
Here is the basic code of the page:
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.");
}
在任何其他浏览器上执行此操作时,处理程序正确返回并上传文件。但是,对于iOS,ashx页面有错误请求正文流耗尽。
When doing this on any other browser, the handler returns correctly and uploads the file. However, with iOS the ashx page has the error "request body stream exhausted".
以下是检查员的屏幕截图:
Here is a screenshot of the inspector:
任何想法?
更新:仅当在IIS中为应用程序启用NTLM / Windows身份验证时,才会出现此问题。使用表单或匿名身份验证,上传工作正常。
UPDATE: This issue only occurs when NTLM/Windows authentication is enabled for the application in IIS. With forms or anonymous authentication, the upload works fine.
谢谢,
John
推荐答案
在iOS 6中,Safari使用初始帖子(包括文件)发送文件。这意味着文件流结束或耗尽。
In iOS 6, Safari sends the file with the initial post, including the file. That means the file stream is at the end, or "exhausted."
然而,对于NTLM,它将在响应中获得401质询,然后必须使用身份验证信息重新发送帖子。由于它不重置文件流,因此无法使用第二个帖子再次发送文件。您可以在IIS日志中看到这一点。
However, with NTLM, it will get a 401 challenge in response, and then have to resend the post with the authentication information. Since it does not reset the file stream, it is unable to send the file again with the second post. You can see this in the IIS logs.
据我所知,没有特别好的方法。我正在更改我的移动应用程序,以便它使用表单身份验证。我将移动应用程序指向同一服务器上的单独登录应用程序,该服务器设置为使用Windows身份验证。然后登录应用程序可以使用表单身份验证cookie重定向回主应用程序,一切都很好。
As far as I know, there is no particularly good way around it. I am changing my mobile app, so that it uses form authentication. I direct the mobile app to a separate login app on the same server, which is set to use Windows Authentication. The login app can then redirect back to the main app with a form authentication cookie, and all is well again.
您必须在两个应用程序中设置机器密钥web.config文件,因此两者都使用相同的密钥进行加密和验证。
You have to set the machine key on both apps in the web.config file, so that both are using the same keys for encryption and validation.
登录应用程序上的代码就像
The code on the login app is as simple as
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
这篇关于iOS 6(iPhone / iPad)图片上传“Request Body Stream Exhausted”使用NTLM / Windows身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!