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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 19:54:39