问题描述
更新
TL;DR:这可能是 Safari 和/或 Webkit 中的错误.
TL;DR: This is potentially a bug in Safari and/or Webkit.
更长的 TL;DR:在 Safari 中,在使用 Fetch API 发出 GET 请求后,Safari 会在页面重新加载时自动(且无意地)重新运行该请求 即使发出请求的代码被删除.
Longer TL;DR: In Safari, after the Fetch API is used to make a GET request, Safari will automatically (and unintentionally) re-run the the request when the page is reloaded even if the code that makes the request is removed.
新发现的最小可重现代码(以下由 Kaiido 提供):
Newly discovered minimal reproducible code (courtesy of Kaiido below):
前端
<script>fetch('/url')</script>
原帖
我有一个 javascript Web 应用程序,它使用 fetch API 在 Node.js (express) 服务器上发出 GET 请求.
I have a javascript web application which uses the fetch API to make a GET request on a Node.js (express) server.
在 Safari 中(问题出在哪里):请求按预期完成.
In Safari (where the problem is):The request completes as expected.
但是
当我重新加载页面时,它会重新发送 GET 请求,从而导致重复.
When I reload the page it will resend the GET request and thus cause duplicates.
在 Chrome 中(作为控件):一切正常(即没有重复).
In Chrome (acting as control):Everything works (ie no duplicates).
HTML
<div id="buttonTarget"></div>
前端 JS
class ErrorReproduce{
constructor(){}
makeButton(){
let button = document.createElement('button');
button.innerText = 'Send get request';
button.onclick = ()=>{
this.asyncMethod();
};
buttonTarget.appendChild(button);
}//end makeButton()
async asyncMethod(){
let data = await fetch('path/to/testError', {
method: 'GET',
cache:'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
},
}).then(response => response.json());
}//end asyncMethod
}//end ErrorReporduce
let errRepro = new ErrorReproduce();
errRepro.makeButton();
后端 JS
router.get('path/to/testError',(req,res)=>{
res.send({ok:true});
})
如何重现
点击按钮 - 查看日志中的 GET 请求
Click button - see the GET request in the log
无需重新点击按钮即可重新加载页面 - 查看日志中的重复请求
Reload page WITHOUT re-clicking the button - see the duplicate request in the log
预期行为
我希望在单击按钮并重新加载页面而不再次按下按钮后不会出现重复请求,但在页面重新加载后浏览器确实会立即重复请求.
I expect that after clicking the button and reloading the page WITHOUT pressing the button again that there will not be a duplicate request, but the request is indeed duplicated IMMEDIATELY by the browser after the page reloads.
Safari 页面重新加载后的服务器日志(错误):
Server log after page reload Safari (error):
GET/path/to/testError 304 3.206 ms - -
GET /path/to/testError 304 3.206 ms - -
...(其他正常请求)...
... (other normal requests) ...
页面重新加载 Chrome 后的服务器日志(预期):
Server log after page reload Chrome (expected):
...(其他正常请求)...
... (other normal requests) ...
编辑
我尝试将 type 属性设置为按钮"(错误仍然存在)
I tried setting the type attribute of the to 'button' (bug persists)
我尝试使用 CMD+R 和重新加载页面按钮(两者都有错误)
I tried using CMD+R and the Reload page button (bug in both)
错误报告链接
推荐答案
Bug 已在 WebKit 中修复.链接到 webkit 中的变更集 247276
Bug has been fixed in WebKit. Link to Changeset 247276 in webkit
这篇关于为什么 Safari 复制 GET 请求而 Chrome 没有?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!