2014-12-24 21 views
8

Chúng tôi gặp sự cố trong một trong các ứng dụng web sản xuất của chúng tôi, nhưng chỉ trên iPad/iOS8.Lỗi Ajax với JQuery trên iPad

Về cơ bản, trong ứng dụng của chúng tôi, người dùng đang thêm sản phẩm vào giỏ hàng của mình, bằng cách nhấn vào hình ảnh đại diện cho các sản phẩm khác nhau. Khi một hình ảnh được khai thác, sản phẩm được "chọn" và một cuộc gọi không đồng bộ ajax được thực hiện; cuộc gọi này cập nhật giỏ hàng của chúng tôi. Mỗi cuộc gọi không đồng bộ kéo dài khoảng 5-10 giây.

Sự cố xảy ra (nhưng chỉ trên iPad, không phải trên máy tính để bàn Chrome, v.v.) khi người dùng nhấp nhiều lần theo thứ tự. Sau đó, cuộc gọi ajax thứ n thất bại với "lỗi 0". Lưu ý: chúng tôi không thể chặn cuộc gọi ajax thứ hai khi cuộc gọi đã được thực hiện (vì một số câu trả lời sẽ đề xuất), vì giỏ hàng sẽ không được cập nhật đúng cách.

Tôi đã theo dõi xuống hành vi này trong một ví dụ jsFiddle bạn có thể tìm thấy ở đây:

http://jsfiddle.net/oc1ktv6u/30/

function updateCart() 
{ 
var data = { 
     json: $.toJSON({ 
      text: 'some text', 
      array: [1, 2, 'three'], 
      object: { 
       par1: 'another text', 
       par2: [3, 2, 'one'], 
       par3: {} 
      } 
     }), 
     delay: Math.round(Math.random()*12) 
} 

$.ajax({ 
    url:"/echo/json/", 
    data:data, 
    type:"POST", 
    success:function(response) 
    { 
     $(".target").append("+"); 
    }, 
    error:function(xhr, ajaxOptions, thrownError) 
    { 
     alert("There was an error in the ajax call: ["+xhr.status+"] ["+thrownError+"]"); 
    } 
}); 

} 

câu hỏi chính của tôi là:

  • Tại sao điều này xảy ra (và tại sao , rõ ràng, chỉ trên iPad/Safari)?
+1

Kiểm tra chủ đề này cho những hạn chế kết nối http://stackoverflow.com/questions/2940559/iphone-mobile-safari-how-many-max-parallel-http-connections –

+0

Lỗi này có thể được sao chép trong fiddle của bạn. Nhấp vào liên kết và cố gắng làm mới trang jsfiddle.net trên trình duyệt của bạn. Thông báo lỗi của bạn sẽ xuất hiện trên cảnh báo. Tôi nghĩ rằng nó là một cái gì đó khác hơn là kết nối song song. Tôi nghĩ rằng sự chậm trễ gây ra lỗi này. Hãy thử câu hỏi này http://jsfiddle.net/oc1ktv6u/42/ –

Trả lời

0
  1. khối các nhấp chuột khi ajax đang hoạt động
  2. sử dụng preventDefault không theo liên kết
Please click <a href="#" id="aia">here</a> many times on iPad/Safari. 
    <div class='target'> 
     Result: 
    </div> 
$(function() { 
    var active = false; 
    $("#aia").on("click",function(e) { 
    e.preventDefault(); 
    if (active) return; 
    active=true; 
    var data = { 
     json: $.toJSON({ 
     text: 'some text', 
     array: [1, 2, 'three'], 
     object: { 
      par1: 'another text', 
      par2: [3, 2, 'one'], 
      par3: {} 
     } 
     }), 
     delay: Math.round(Math.random()*12) 
    } 

    $.ajax({ 
    url:"/echo/json/", 
    data:data, 
    type:"POST", 
    success:function(response) { 
     $(".target").append("+"); 
     active=false; 
    }, 
    error:function(xhr, ajaxOptions, thrownError) { 
     alert("There was an error in the ajax call: ["+xhr.status+"] ["+thrownError+"]"); 
    } 
    }); 
}); 
+0

Xin chào, tôi muốn cuộc gọi kích hoạt ngay cả khi cuộc gọi khác đang chạy. Điều này bởi vì trong ứng dụng thực sự của chúng tôi, neo không phải là một liên kết mà là một hình ảnh bật/tắt. –

+0

Sau đó, bạn cần phải sắp xếp các cuộc gọi. Có một cái nhìn cho hàng đợi và lời hứa, nhưng nhìn vào ngày của đề nghị quá – mplungjan

+0

Cảm ơn. Bạn có biết lý do của hành vi này trên iPad không? –

0

Bạn có thể muốn thử điều này:

var xhr = null; 

function aia(){ 
    if (xhr == null) 
     xhr = $.ajax({ 
      //... 
      success: function(data){ 
       xhr = null; 
      } 
      //... 
     }); 
} 
+0

Không, xin lỗi, có lẽ câu hỏi của tôi không rõ ràng. Cuộc gọi ajax phải được thực hiện ngay cả khi cuộc gọi khác đang chạy. –

+0

Theo tôi, trạng thái 0 có nghĩa là yêu cầu xhr đã bị hủy hoặc kết nối bị gián đoạn vì một số lý do. Vì vậy, có bạn đã cố gắng để hạn chế số lượng yêu cầu ajax đồng thời bằng cách tạo ra một số loại hàng đợi? – nquocnghia

+0

Vâng, chúng tôi đã nghĩ đến hàng đợi, có lẽ nó sẽ hoạt động. Nó sẽ là thú vị để biết, tuy nhiên, tại sao yêu cầu bị hủy bỏ (tại sao chỉ trên iPad?) Và nếu chúng ta đang đạt một số loại giới hạn. –

3

Như câu trả lời khác đã đề cập, bạn nên có một hàng đợi để xử lý các yêu cầu và chắc chắn rằng họ đang được xử lý theo thứ tự chúng được tạo ra:

var active = false; 
var requests = []; 

var updateCart = function (data) { 
if(active) { 
    requests.push(data); 
} else { 
    $.ajax({ 
     type: 'POST', 
     url: url, 
     data: data, 
     beforeSend: function() { 
      active = true; 
      //show loading on the cart symbol or something to tell the user there is a process going on, UX goodness 
     }, 
     success : function() { 
      active = false; 
      if(requests.length > 0) { 
       next = requests.shift(); 
       updateCart(next); 
      } 
     } 
    }); 
}; 

Trang web này dường như đưa ra một số cái nhìn sâu sắc vào số lượng kết nối hiện hoạt có sẵn cùng một lúc và bạn có thể thử nghiệm trên iPad của mình http://www.browserscope.org/?category=network

Tôi tự chạy nó và đề cập đến 17 kết nối tối đa, nhưng tôi cũng tò mò về mạng bạn đang sử dụng iPad, nếu nó chậm hơn, nói trên 3G hoặc Edge, hơn những kết nối này có thể sao lưu khá nhanh . Tôi đã thử nghiệm iPad của tôi trên Wifi và không thể tái tạo lỗi của bạn trên Fiddle. Hy vọng rằng điều này giúp ít nhất là chẩn đoán vấn đề.

+0

Cảm ơn câu trả lời của bạn. Bạn đang sử dụng iPad nào (phiên bản và phiên bản hệ điều hành) ?. Để tái tạo lỗi, tôi phải nhấn nhanh vào liên kết và khoảng 50-100 lần. Tôi đang ở trên Wi-Fi bình thường. –

+0

iPad của tôi là Air (Thế hệ thứ nhất) và trên iOS 8.1. Tôi thành thật không cố gắng 50-100 nhấp chuột, có thể 30-50 mặc dù điều đó dường như rất quá mức đối với trang Ứng dụng web trừ khi đó là một loại trò chơi nào đó. Tôi sẽ đề nghị nếu bạn muốn thử nghiệm những thứ như thế này vượt xa sự tương tác thủ công, hãy sử dụng một bộ thử nghiệm như Selenium cho Firefox hoặc Sahi - nhưng một lần nữa, điều này có vẻ như rất nhiều quá trình xử lý sẽ được xử lý bởi hệ thống xếp hàng hoặc một quy trình xử lý việc thêm nhiều mục vào giỏ hàng cùng một lúc, thay vì từng mục một. – Codermonk

+0

Thật không may điều này đã xảy ra trong cuộc sống thực trên một trong các ứng dụng sản xuất của chúng tôi: ai đó đã khai thác 50 lần liên tiếp trên iPad. Nhưng bạn biết đấy, phần mềm phải mạnh mẽ và nhiệm vụ của chúng tôi là nhà phát triển là xử lý ngay cả những trường hợp góc kỳ lạ như vậy. –

0

Làm việc với các phiên bản mới nhất của jquery trong fiddle sau: http://jsfiddle.net/oc1ktv6u/41/

HTML

<body> 
    Please click <a href="#" id="js">here</a> many times on iPad/Safari. 
    <div class='target'> 
     Result: 
    </div> 
    <br /> 
     <div id='log'> 
    </div> 
</body> 

JAVASCRIPT

var i=0; 
$('#js').on('touchstart click',function() { 
      var data = { 
      text: 'some text', 
      array: [1, 2, 'three'], 
      object: { 
       par1: 'another text', 
       par2: [3, 2, 'one'], 
       par3: {} 
      } 
     } 
var jsondata = JSON.stringify(data);   
var request = $.ajax({ 
url:"/echo/json/", 
type: "POST", 
data: jsondata, 
dataType: "json" 
}); 
request.done(function(msg) { 
$(".target").append("+"); 
    i++; 
$("#log").html('clicked '+ i + 'times'); 
}); 
request.fail(function(jqXHR, textStatus) { 
alert("Request failed: " + textStatus); 
}); 
}); 
+0

Bạn không có sự chậm trễ trong cuộc gọi ajax của bạn ... –

+0

Có nhu cầu thực sự về sự chậm trễ không? Mục đích của sự chậm trễ ở nơi đầu tiên là gì? –

+0

Có. Vấn đề phát sinh với các kết nối đồng thời. Nếu bạn loại bỏ sự chậm trễ, không có đồng thời. –