最近發現了一個ajax
非同步請求的問題,用$.post
、$.get
、$.ajax
請求PHP伺服器時,總是無法非同步返回資料。
經過多次測試才發現:
– 不同瀏覽器,請求不同域名-不阻塞:無需實驗
– 不同瀏覽器,請求同域名-不阻塞:session_id()
返回不同
– 同一瀏覽器,請求不同域名-不阻塞:session_id
返回不同
– 同一瀏覽器,請求同域名-阻塞:session_id()
傳回相同
發現問題所在:
1 關閉XDEBUG
2 SESSION
鎖定
3 清除輸出緩衝區
1 關閉XDEBUG
XDEBUG
是即時偵錯。調試時,它將保持FPM
以確保線程正在工作以避免資料污染。
典型的測試方法是,使用XDEBUG
進行調試時,打開另一個瀏覽器並訪問該站點,該站點這個時候是無法訪問的。
這對平行回應有重大影響,即,即使前端發送多個請求,它也受XDEBUG
控制,並且只能同時回應一個。
另外,由於XDEBUG
依賴SESSION
,因此即使您使用session_write_close()
,也要關閉會話鎖定(請參閱下文)。 XDEBUG
仍會自動開啟。
2 SESSION
鎖定
用session_write_close()
關閉SESSION
的寫鎖,這適合SESSION
儲存為File
的情況。如果SESSION
保存在Redis
,則不需要。
3 清除輸出緩衝區
使用session_write_close()
可能無法立即關閉SESSION
鎖定,所以在這個方法之前加上:ob_end_flush()
。讓 session_write_close()
馬上生效。
4 範例
有如下一個範例,當點選【提交】按鈕時,前端會傳送兩個請求給後台伺服器。
一種是get
請求,每隔1秒鐘請求一次。
一種是post
請求,最開始的時候發送一次,然後等待對應結束。
看看HTML代碼
<form> <input type="submit" value="提交" /> </form> <script src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script> <script type="text/javascript"> $('form').on('submit', function(e) { e.preventDefault(); // 每隔一秒请求一次服务器 var id = setInterval(function() { $.get( 'save.php?action=get', {}, function(data) { console.log(data); }, 'json' ); }, 1000); $.post( 'save.php?action=post', {}, function(data) { console.log(data); // 停止定时循环 clearInterval(id); }, 'json' ); }); </script>
php代碼
<?php session_start();$action = $_GET['action']; if ($action == 'post') { $_SESSION['time'] = 0; session_write_close(); while ($_SESSION['time'] < 5) { session_start(); $_SESSION['time'] = $_SESSION['time'] + 1; // 将SESSION数据写入文件中,并关闭写锁 session_write_close(); // sleep()模拟花费时间较长的程序,这样在关闭写锁之后, // 服务器就能够相应别的请求,如下的$action=get, sleep(1); } echo json_encode([session_id() => $_SESSION['time']]); exit();}if ($action == 'get') { echo json_encode([session_id() => $_SESSION['time']]); exit();}
推薦學習:《PHP視頻教程》
以上是非同步請求PHP伺服器,不回傳資料? (附解決辦法)的詳細內容。更多資訊請關注PHP中文網其他相關文章!