You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel+Web Worker轮询Fetch返回异常问题求助

Web Worker轮询数据库始终返回"未找到"的排查与解决

我需要通过Web Worker轮询数据库中的指定值,逻辑是当值存在时终止Worker并刷新页面,但目前遇到问题:即使数据库已有目标数据,Fetch查询始终返回"belum"(未找到),无法触发后续终止和刷新操作。

相关代码

1. 主页面JS代码

$.post('{{ url('') }}/input-data-finger', $("#finger-form").serialize())
    .done(function(response) {
        var myModal = new bootstrap.Modal(document.getElementById('loadfinger'), {
            keyboard: false
        })
        myModal.show();

        let id = $('#nama').val();
        let token = document.querySelector('input[name=_token]').value;

        var work = new Worker("/js/fingerwait.js");
        work.postMessage([id,token]);

        work.onmessage = function(event) {
            if (event.data == 'ok') {
                work.terminate();
                work = undefined;
                let test = $('#icon-gif').attr({
                    trigger: 'in',
                    delay: '2000',
                    state: 'morph-correct'
                });
                $('#fingernotif').text('Data Fingerprint Berhasil Di Daftarkan');
                $('#fingernotif-2').text('Page Akan Refresh Secara Otomatis');
                work = new Worker("/js/fingerdone.js");
                work.onmessage = function(response) {
                    if (response.data == 'ok') {
                        work.terminate();
                        work = undefined;
                        location.reload();
                    }
                }
            } else {
                console.log(event.data);
            }
        }
    }).fail(function(response) {
        var data = JSON.parse(response.responseText);
        if (data.errors.nama_pengajar != null) {
            $('.err_nama').empty().append(
                `<span class="text-danger" style="font-size:15px">${data.errors.nama_pengajar}</span>`
            );
        }
        if (data.errors.jadwal_pengajar != null) {
            $('.err_jadwal').empty().append(
                `<span class="text-danger" style="font-size:15px">${data.errors.jadwal_pengajar}</span>`
            );
        }
    })

2. fingerwait.js代码

var id_p;
var token;

const cekInterval = setInterval(() => {

    onmessage = (e) => {
        id_p = e.data[0];
        token = e.data[1];
    }

    fetch(`{{ url('') }}/cek-pengajar-finger/${id_p}`, {
        method: 'GET',
        headers: {
            "X-CSRF-Token": token
        },
    }).then(function (response) {
        if (response == 'ok') {
            postMessage('ok');
        } else {
            postMessage('belum');
        }
    }).catch(function (err) {
        postMessage(err);
    })
}, 3000);

3. Laravel后端cekFinger方法

public function cekFinger($id)
{
    $data = fingerprint::where('pengajar_id', $id)->first();
    if ($data == null) {
        return response('no', 406);
    } else {
        return response('ok', 200);
    }
}

问题排查与修复

1. Fetch响应处理逻辑错误

fetch返回的response是一个Response对象,并非直接的文本内容,直接判断response == 'ok'永远不会成立。需要先读取响应文本,再进行判断:

修改fingerwait.js中的Fetch处理部分:

fetch(`{{ url('') }}/cek-pengajar-finger/${id_p}`, {
    method: 'GET',
    headers: {
        "X-CSRF-Token": token
    },
}).then(function (response) {
    // 先判断HTTP状态码,非200直接返回未找到
    if (!response.ok) {
        postMessage('belum');
        return;
    }
    // 读取响应文本
    return response.text();
}).then(function (text) {
    if (text === 'ok') {
        postMessage('ok');
        clearInterval(cekInterval); // 找到数据后清除定时器,避免无效轮询
    } else {
        postMessage('belum');
    }
}).catch(function (err) {
    postMessage(err.message);
})

2. Worker消息监听位置错误

将onmessage绑定放在setInterval内部,会导致每次定时器触发都重新绑定监听,可能造成参数接收异常。应将监听放在定时器外部,仅绑定一次:

调整fingerwait.js的结构:

var id_p;
var token;

// 仅绑定一次消息监听,接收主页面传递的参数
onmessage = (e) => {
    id_p = e.data[0];
    token = e.data[1];
};

const cekInterval = setInterval(() => {
    // 确保参数已接收后再发起请求
    if (!id_p || !token) return;

    fetch(`{{ url('') }}/cek-pengajar-finger/${id_p}`, {
        method: 'GET',
        headers: {
            "X-CSRF-Token": token
        },
    }).then(function (response) {
        if (!response.ok) {
            postMessage('belum');
            return;
        }
        return response.text();
    }).then(function (text) {
        if (text === 'ok') {
            postMessage('ok');
            clearInterval(cekInterval);
        } else {
            postMessage('belum');
        }
    }).catch(function (err) {
        postMessage(err.message);
    })
}, 3000);

3. 额外调试建议

  • 在Worker中添加console.log(id_p, token),确认参数是否正确接收
  • 查看浏览器Network面板中cek-pengajar-finger请求的实际响应内容和状态码
  • 后端添加日志,确认接收到的id是否正确,以及数据库查询结果是否符合预期

内容的提问来源于stack exchange,提问作者SomeDude

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 09:30:57