【问题标题】:iOS 6 (iPhone/iPad) Image Upload "Request Body Stream Exhausted" with NTLM/Windows AuthenticationiOS 6 (iPhone/iPad) 使用 NTLM/Windows 身份验证的图像上传“请求正文流已用尽”
【发布时间】:2012-09-23 13:03:09
【问题描述】:

我正在尝试让 iOS 6 使用 XMLHttpRequest POST 上传图像。这适用于桌面和 Android 网络浏览器,但在 iOS 6 上,我在发布到的页面上收到错误:“请求正文流已用尽”。 (将 iOS 模拟器与 Safari Web Inspector 结合使用)。

这是页面的基本代码:

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 xmlhttprequest ios-simulator ios6 xmlhttprequest-level2


    【解决方案1】:

    在 iOS 6 中,Safari 将文件与初始帖子一起发送,包括文件。这意味着文件流已结束,或“用尽”。

    但是,使用 NTLM,它会收到 401 挑战作为响应,然后必须重新发送带有身份验证信息的帖子。由于它不会重置文件流,因此无法使用第二个帖子再次发送文件。您可以在 IIS 日志中看到这一点。

    据我所知,没有特别好的解决方法。我正在更改我的移动应用程序,以便它使用表单身份验证。我将移动应用程序定向到同一服务器上的单独登录应用程序,该应用程序设置为使用 Windows 身份验证。然后登录应用可以使用表单身份验证 cookie 重定向回主应用,一切都恢复正常。

    您必须在 web.config 文件中为两个应用程序设置机器密钥,以便两者使用相同的密钥进行加密和验证。

    登录应用上的代码很简单

    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
    

    【讨论】:

    • 这确实是我也观察到的。您的解决方案很有趣。暂时(我已经向 Apple 提交了一个错误,看看他们是否可以修复它),我实际上将文件上传到了一个未经身份验证的 iframe 中,该 iframe 将文件上传到 ASP.NET 临时文件夹并传回一个令牌然后在从临时文件夹中检索文件时,经过身份验证的页面用于引用。
    • 有解决方法吗?也许使用 WCF,或者使用其他技术?我在 SharePoint 上,需要 Windows 身份验证。
    【解决方案2】:

    我通过在 iOS 7 和 iOS 8 上不设置自定义 HTTP Authenticate Head 解决了这个问题。(起初,我们的服务使用自定义的 Authenticate Head 值)。并且在委托处理挑战后,请求将自动具有“自动验证:NTLMxxx”标头。并且 Put 和 POST 再次起作用。

    【讨论】:

      【解决方案3】:

      此错误出现在 IOS 上,但您可以使用不同的方法 比如在你追加文件的地方更改你的代码行

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

      到下面一行基本上不附加文件控件而是使用base64图像数据

      var reader = new FileReader();
      
      reader.readAsDataURL(opmlFile.files[0]);
      
      reader.onload = function () {
      
          var base64DataImg = reader.result;            
      
          base64DataImg = base64DataImg.replace('data:'imagetype';base64,', '');      
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-06-12
        • 1970-01-01
        • 2019-05-11
        • 2016-03-24
        • 1970-01-01
        • 2021-07-05
        • 1970-01-01
        相关资源
        最近更新 更多