我正在尝试让 iOS 6 使用 XMLHttpRequest POST 上传图片。这适用于桌面和 Android 网络浏览器,但对于 iOS 6,我在发布到的页面上收到错误消息:“请求正文流耗尽”。 (将 iOS 模拟器与 Safari Web 检查器结合使用)。
页面的基本代码如下:
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 页面出现错误“请求正文流耗尽”。
这是检查器的屏幕截图:
有什么想法吗?
更新:此问题仅在为 IIS 中的应用程序启用 NTLM/Windows 身份验证时发生。使用表单或匿名身份验证,上传工作正常。
谢谢,
约翰
最佳答案
在 iOS 6 中,Safari 发送带有初始帖子的文件,包括文件。这意味着文件流已结束,或“耗尽”。
但是,对于 NTLM,它将收到 401 质询作为响应,然后必须重新发送带有身份验证信息的帖子。由于它没有重置文件流,因此无法通过第二个帖子再次发送文件。您可以在 IIS 日志中看到这一点。
据我所知,没有特别好的解决办法。我正在更改我的移动应用程序,以便它使用表单例份验证。我将移动应用程序定向到同一服务器上的单独登录应用程序,该应用程序设置为使用 Windows 身份验证。然后,登录应用程序可以使用表单例份验证 cookie 重定向回主应用程序,一切都恢复正常。
您必须在 web.config 文件中为两个应用程序设置机器 key ,以便它们使用相同的 key 进行加密和验证。
登录应用的代码很简单
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
关于带有 NTLM/Windows 身份验证的 iOS 6 (iPhone/iPad) 图片上传 "Request Body Stream Exhausted",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12694310/