iOS浏览器切后台/最小化时Fetch请求中断及会话保持问题求助
iOS浏览器切后台/最小化时Fetch请求中断及会话保持问题求助
嗨,我正在开发一个基于Laravel、Nginx服务器和Express API的Web应用,最近碰到了个iOS端特有的头疼问题:当用户切换标签页或者把浏览器最小化时(目前只在iOS的Chrome和Safari上测试过),Fetch请求好像会中断,会话状态也跟着丢了,但桌面端完全正常。
具体来说,用户需要暂时离开当前标签页去其他应用完成验证操作,等他们返回浏览器时,我希望会话依然活跃,之前的状态不会丢失,但现在实际情况是回来后流程直接断了,没法继续。我的目标就是让用户在暂时 inactive 一段时间后返回,还能从之前中断的地方接着操作。
有没有小伙伴遇到过类似的情况?求问最佳的处理方案是什么?
下面是我目前的部分代码:
前端视图中的Fetch请求代码
try { const response = await fetch('https://miapi.thisisworking.com/puppeteer/webscrape', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ data1, data2}) }); if (!response.body) { throw new Error("Empty response"); } const reader = response.body.getReader(); const decoder = new TextDecoder(); let receivedText = ""; while (true) { const { done, value } = await reader.read(); if (done) break; const chunk = decoder.decode(value, { stream: true }); receivedText += chunk; const dataJSON = JSON.parse(chunk); if (dataJSON.success && dataJSON.verificationCode) { verificationDiv.innerText = `Verification code: ${dataJSON.verificationCode}`; } else { verificationDiv.innerText = 'Error to get code.'; } } const jsonParts = receivedText.split('\n').map(part => part.trim()).filter(part => part.length > 0); if (jsonParts.length === 0) { throw new Error("Didn't get the JSON data"); } const lastJson = jsonParts[jsonParts.length - 1]; let dataFromResponse; try { dataFromResponse = JSON.parse(lastJson); } catch (error) { console.error("Error parsing JSON:", error); alert("Error."); return; } const data = dataFromResponse.data; const name = data.name; const email = document.getElementById('email').value; const password = document.getElementById('password').value; function centsConvert(valor) { const convertValue = valor.replace('.', '').replace(',', '.'); return Math.round(parseFloat(convertValue) * 100); } registrationData = { name: data.name, full_name: data.name, email: document.getElementById('email').value, telefono: document.getElementById('telefono').value, password: document.getElementById('password').value, dni: data.dni, }; step2Container.style.display = 'block'; let divVerification = document.getElementById('verificationCode'); divVerification.innerText = ''; let containerSpinner = document.getElementById('spinner-container'); containerSpinner.style.display = 'none'; } finally { spinnerContainer.style.display = 'none'; btn.disabled = false; }
Express API端代码
app.post('/puppeteer/webscrape', async (req, res) => { const { dni, fecha } = req.body; const dniRegex = /^\d{8}[A-Za-z]$/; const fechaRegex = /^\d{4}\-\d{2}\-\d{2}$/; if (!dniRegex.test(dni)) { return res.status(400).json({ error: 'Invalid DNI.' }); } if (!fechaRegex.test(fecha)) { return res.status(400).json({ error: 'Invalid date.' }); } try { res.setHeader('Content-Type', 'application/json'); res.setHeader('Transfer-Encoding', 'chunked'); res.write(JSON.stringify({ success: true, message: 'Started process.' }) + '\n'); res.flushHeaders(); setImmediate(async () => { try { const { success, verificationCode, error } = await initializeBrowser(dni, fecha); if (!success) { logError(`Error en la inicialización: ${error}`); return; } const name = await handleRedirectionAndClick(dni); if (name) { console.log('Finished:', apellidosYNombres); } else { logError('Error'); } } catch (err) { logError(`Error: ${err}`); } }); } catch (error) { console.log(error); logError(`Error: ${error}`); res.write(JSON.stringify({ error: 'Error.' })); res.end(); } });
再次说明:这个问题只在移动端iOS上出现,桌面端完全正常。
备注:内容来源于stack exchange,提问作者fcoterroba
相关产品推荐
相关产品推荐

