7

Tôi đang cố gắng để có được iOS 6 sử dụng các bài đăng XMLHttpRequest để tải lên hình ảnh. Tính năng này hoạt động trên trình duyệt web dành cho máy tính để bàn và Android, nhưng với iOS 6, tôi gặp lỗi trên trang được đăng lên: "Yêu cầu luồng nội dung cạn kiệt". (Sử dụng Trình mô phỏng iOS với Trình kiểm tra web Safari).iOS 6 (iPhone/iPad) Tải lên hình ảnh "Yêu cầu luồng nội dung cạn kiệt" với xác thực NTLM/Windows

Đây là mã cơ bản của trang:

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

Khi làm điều này trên bất kỳ trình duyệt nào khác, xử lý trả về một cách chính xác và tải lên các tập tin. Tuy nhiên, với iOS trang ashx có lỗi "yêu cầu luồng cơ thể cạn kiệt".

Đây là một ảnh chụp màn hình của thanh tra:

Request Body Stream Exhausted

Bất kỳ ý tưởng?

CẬP NHẬT: Sự cố này chỉ xảy ra khi xác thực NTLM/Windows được bật cho ứng dụng trong IIS. Với biểu mẫu hoặc xác thực ẩn danh, quá trình tải lên hoạt động tốt.

Cảm ơn,

John

Trả lời

5

Trong iOS 6, Safari gửi tập tin với các bài ban đầu, bao gồm cả các tập tin. Điều đó có nghĩa là luồng tệp ở cuối hoặc "cạn kiệt".

Tuy nhiên, với NTLM, ứng dụng sẽ nhận được thử thách 401 để phản hồi và sau đó phải gửi lại bài đăng có thông tin xác thực. Vì nó không đặt lại luồng tệp, nên không thể gửi tệp lại bằng bài đăng thứ hai. Bạn có thể thấy điều này trong các bản ghi IIS.

Theo như tôi biết, không có cách nào đặc biệt tốt xung quanh nó. Tôi đang thay đổi ứng dụng dành cho thiết bị di động của mình để ứng dụng sử dụng xác thực biểu mẫu. Tôi hướng ứng dụng di động đến ứng dụng đăng nhập riêng trên cùng một máy chủ, được đặt để sử dụng Xác thực Windows. Sau đó, ứng dụng đăng nhập có thể chuyển hướng trở lại ứng dụng chính bằng cookie xác thực biểu mẫu và tất cả đều tốt.

Bạn phải đặt khóa máy trên cả hai ứng dụng trong tệp web.config, để cả hai đều sử dụng cùng một khóa để mã hóa và xác thực.

Các mã trên ứng dụng đăng nhập đơn giản như

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 
+2

Đó thực sự là những gì tôi cũng đã quan sát.Giải pháp của bạn là một giải pháp thú vị. Hiện tại (tôi đã gửi một lỗi cho Apple để xem liệu họ có thể sửa lỗi), tôi thực sự có tệp tải lên trong iframe không được xác thực tải lên tệp vào thư mục temp ASP.NET và chuyển lại mã thông báo sau đó trang được xác thực sẽ sử dụng để tham chiếu khi truy xuất tệp từ thư mục tạm thời. –

+0

Có cách giải quyết nào không? Có thể sử dụng WCF, hoặc có thể sử dụng một số kỹ thuật khác? Tôi đang ở trên SharePoint và cửa sổ auth là một yêu cầu. – harsimranb

0

tôi giải quyết vấn đề này bằng cách không thiết lập HTTP tự xác định Authenticate Head trên iOS 7 và iOS 8. (Lúc đầu, dịch vụ của chúng tôi sử dụng giá trị tự xác định cho Authenticate Head). Và sau khi thử thách được xử lý bởi các đại biểu, yêu cầu sẽ có tiêu đề "Authenticate: NTLMxxx automatic" tự động. Và Put và POST hoạt động trở lại.

0

Lỗi này Đi kèm trên IOS nhưng bạn có thể sử dụng phương pháp khác nhau như thay đổi dòng mã của bạn trong formdata nơi bạn phụ thêm file

var fd = new FormData(); 

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

vào dòng dưới đây về cơ bản không thêm sự kiểm soát tập tin nhưng sử dụng dữ liệu hình ảnh base64

var reader = new FileReader(); 

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

reader.onload = function() { 

    var base64DataImg = reader.result;    

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

} 
Các vấn đề liên quan