非同步請求PHP伺服器,不回傳資料? (附解決辦法)

藏色散人
發布: 2023-04-10 21:34:02
轉載
4848 人瀏覽過

最近發現了一個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">
    $(&#39;form&#39;).on(&#39;submit&#39;, function(e) {
        e.preventDefault();

        // 每隔一秒请求一次服务器
        var id = setInterval(function() {
            $.get(
                &#39;save.php?action=get&#39;,
                {},
                function(data) {
                    console.log(data);
                },
                &#39;json&#39;
            );
        }, 1000);

        $.post(
            &#39;save.php?action=post&#39;,
            {},
            function(data) {
                console.log(data);
                // 停止定时循环
                clearInterval(id);
            },
            &#39;json&#39;
        );
    });
</script>
登入後複製

php代碼

<?php
session_start();$action = $_GET[&#39;action&#39;];
if ($action == &#39;post&#39;) {

   $_SESSION[&#39;time&#39;] = 0;
   session_write_close();

    while ($_SESSION[&#39;time&#39;] < 5) {
      session_start();
      $_SESSION[&#39;time&#39;] = $_SESSION[&#39;time&#39;] + 1;

      // 将SESSION数据写入文件中,并关闭写锁
      session_write_close();

      // sleep()模拟花费时间较长的程序,这样在关闭写锁之后,
      // 服务器就能够相应别的请求,如下的$action=get,
      sleep(1);
    }

    echo json_encode([session_id() => $_SESSION[&#39;time&#39;]]);
    exit();}if ($action == &#39;get&#39;) {
    echo json_encode([session_id() => $_SESSION[&#39;time&#39;]]);
    exit();}
登入後複製

 推薦學習:《PHP視頻教程》                                            

以上是非同步請求PHP伺服器,不回傳資料? (附解決辦法)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
php
來源:learnku.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板