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

两次调用同一PHP脚本的fetch请求为何出现阻塞?

问题分析与解决

你的问题核心是浏览器的同URL请求排队机制,而非PHP会话锁的问题,具体原因和解决方法如下:

核心原因:浏览器的GET请求缓存优化

现代浏览器为了避免重复请求、利用缓存,会对同一域名下的相同URL的GET请求(fetch默认使用GET方法)进行串行排队处理——它会等待第一个请求完成后,再发送第二个请求,以此判断是否可以复用第一个请求的缓存结果。

即便你的PHP脚本已经通过session_write_close()释放了会话锁,服务器端已经可以处理并发请求,但浏览器这边直接把第二个请求按住了,导致它要等第一个请求完成后才会发送,最终总耗时变成20秒。

次要排查点:PHP会话锁的潜在问题(可能性低)

虽然你已经调用了session_write_close(),但如果你的PHP环境开启了session.auto_start,脚本启动时会自动获取会话锁,不过只要session_write_close()在sleep(10)之前执行,锁就会被释放,服务器端不会阻塞第二个请求。可以通过在脚本开头加var_dump(session_status());确认会话状态,确保session_write_close()确实生效。

解决方案

方法1:给URL添加唯一标识

给两个请求的URL加上不同的查询参数,让浏览器认为是不同的请求,从而并发发送:

async function test() {
    fetch('api/v1/test?t=' + Date.now())
    fetch('api/v1/test?t=' + Date.now())
}
test();

方法2:改用POST请求

浏览器不会对POST请求做这种排队优化,直接修改请求方法即可:

async function test() {
    fetch('api/v1/test', { method: 'POST' })
    fetch('api/v1/test', { method: 'POST' })
}
test();

方法3:确认PHP会话操作无遗漏

确保PHP脚本中session_write_close()之后没有再调用任何会话相关函数(比如session_start()、$_SESSION赋值等),避免重新获取会话锁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:31:39