V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
3dwelcome
V2EX  ›  问与答

为什么浏览器 AJAX 的 GET 是幂等的?

  •  
  •   3dwelcome · 2020-12-31 16:14:23 +08:00 · 1344 次点击
    这是一个创建于 1426 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如要 GET 一个 URL 文件,正常访问流程。肯定是浏览器先向服务器去查询文件最后修改时间,然后判断是不是需要重新下载,还是直接跳过。

    可是现在浏览器并不是这样处理,只有 POST 会向服务器请求数据,而 GET 只要 URL 相等(也就是幂等),就默认文件已经最新版了?这合理吗,并不合理吧。

    我知道 GET 屁股后面加个时间戳可以解决问题,但有 304 Not Modified 规范不用,自作聪明直接跳过服务器访问步骤,这点我就很不理解了。

    8 条回复    2021-05-01 00:59:33 +08:00
    mxT52CRuqR6o5
        1
    mxT52CRuqR6o5  
       2020-12-31 16:19:41 +08:00
    百度 [强缓存] 、 [协商缓存]
    mxT52CRuqR6o5
        2
    mxT52CRuqR6o5  
       2020-12-31 16:21:09 +08:00
    所谓的 GET 幂等,是因为服务器告诉浏览器这么做的,是服务器配置有问题
    randyo
        3
    randyo  
       2020-12-31 16:21:37 +08:00
    可以看看 http 缓存机制,就知道理解有没有偏差
    3dwelcome
        4
    3dwelcome  
    OP
       2020-12-31 16:25:51 +08:00
    @mxT52CRuqR6o5 我服务器缓存设置没问题,默认浏览器用 GET 访问很好,正常返回 304 。但是放在 AJAX 里运行,就是不行。

    我就想问问,同样是 GET,有什么理由要区别对待?

    而且我也不想用 POST,或者完全关缓存。GET 查个 HTTP HEAD 询问服务器,文件有没有最新版本,这不是常规操作吗?怎么到 AJAX 里,就变得那么复杂。
    oott123
        5
    oott123  
       2020-12-31 16:55:10 +08:00 via Android
    你是 Safari 受害者吗? Safari 在这种情况下的实现并不规范,是它自作聪明。
    3dwelcome
        6
    3dwelcome  
    OP
       2020-12-31 17:01:48 +08:00
    Google 了一下,看了 RFC,终于知道什么叫幂等,原来不是网上流传的谣言,是 URL 相等,和重复提交有关系。是通知浏览器,如果 GET 一半网络断开后重连,可以后台自动重新发送数据的意思。
    POST 不是幂等请求,所以断网几秒后自动恢复,服务器是不会重新去执行一次提交的。
    这点在 DELETE 上也有说明,服务器要处理这种情况,就是为了防止客户端多次提交相同的 URL,结果会不可预测。
    3dwelcome
        7
    3dwelcome  
    OP
       2020-12-31 17:03:28 +08:00
    POST 不是幂等请求,所以断网几秒后自动恢复,浏览器是不会重新去执行一次提交的。

    论坛打错字不能编辑好烦啊,回帖就不能学学发帖,2 分钟内允许自己编辑吗?
    3dwelcome
        8
    3dwelcome  
    OP
       2021-05-01 00:59:33 +08:00
    总结一下结局吧,免得虎头蛇尾,虽然没人看。

    在 Ajax 中,需要加上 max-age=0, GET 才能获取新数据( https://stackoverflow.com/questions/38661942/ajax-304-not-modified-cant-receive-response)

    如果不设置 max-age, 浏览器会自动猜测资源过期时间( https://stackoverflow.com/questions/14345898/what-heuristics-do-browsers-use-to-cache-resources-not-explicitly-set-to-be-cach/31852117#31852117)

    浏览器 F5 和地址栏回车输入不算,会假设 max-age=0, 正常取得 304 Not Modify
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5504 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 08:02 · PVG 16:02 · LAX 00:02 · JFK 03:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.