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
相关产品推荐
相关产品推荐

