当前位置: 首页 > news >正文

是否可以在HTTP中缓存POST方法

如果您想知道是否可以缓存post请求,并尝试研究该问题的答案,那么您很可能不会成功。当搜索“缓存post请求”时,第一个结果是这个StackOverflow问题。

答案是令人困惑的,包括缓存应该如何工作,缓存如何根据RFC工作,缓存应该如何根据RFC工作,以及缓存在实践中如何工作。让我们从RFC开始,逐步演示浏览器的实际工作方式,然后讨论CDN、GraphQL和其他值得关注的领域。

RFC 2616

根据RFC,POST请求必须使缓存无效:

13.10 Invalidation After Updates or Deletions..Some HTTP methods MUST cause a cache to invalidate an entity. This is
either the entity referred to by the Request-URI, or by the Location
or Content-Location headers (if present). These methods are:- PUT- DELETE- POST

复制

这种语言表明POST请求是不可缓存的,但事实并非如此(在本例中)。高速缓存仅对先前存储的数据无效。RFC (似乎)明确说明,是的,您可以缓存POST请求:

9.5 POST..Responses to this method are not cacheable, unless the response
includes appropriate Cache-Control or Expires header fields. However,
the 303 (See Other) response can be used to direct the user agent to
retrieve a cacheable resource.

复制

尽管使用这种语言,但设置Cache-Control时不得缓存对同一资源的后续POST请求。必须将POST请求发送到服务器:

13.11 Write-Through Mandatory..All methods that might be expected to cause modifications to the
origin server's resources MUST be written through to the origin
server. This currently includes all methods except for GET and HEAD.
A cache MUST NOT reply to such a request from a client before having
transmitted the request to the inbound server, and having received a
corresponding response from the inbound server. This does not prevent
a proxy cache from sending a 100 (Continue) response before the
inbound server has sent its final reply.

复制

这怎么说得通呢?您不是在缓存POST请求,而是在缓存资源。

对于对同一资源的后续GET请求,只能缓存POST响应正文。在POST响应中设置LocationContent-Location标头,以传达正文所代表的资源。因此,在技术上缓存POST请求的唯一有效方法是对相同资源的后续GET。

正确答案是两者兼而有之:

  • “是的,RFC允许您将后续GET的POST请求缓存到相同的resource"
  • "no,。RFC不允许您缓存后续POST的POST请求,因为POST不是幂等的,必须直接写入服务器”

尽管RFC允许缓存对同一资源的请求,但实际上,浏览器和CDN不会实现此行为,也不允许您缓存POST请求。

资料来源:

  • https://www.rfc-editor.org/rfc/rfc2616#section-13 HTTP/1.1 RFC
  • https://www.mnot.net/blog/2012/09/24/caching_POST

浏览器行为演示

给定以下示例JavaScript应用程序(index.js):

const express = require('express')
const app = express()let count = 0app.get('/asdf', (req, res) => {count++const msg = `count is ${count}`console.log(msg)res.set('Access-Control-Allow-Origin', '*').set('Cache-Control', 'public, max-age=30').send(msg)}).post('/asdf', (req, res) => {count++const msg = `count is ${count}`console.log(msg)res.set('Access-Control-Allow-Origin', '*').set('Cache-Control', 'public, max-age=30').set('Content-Location', 'http://localhost:3000/asdf').set('Location', 'http://localhost:3000/asdf').status(201).send(msg)}).set('etag', false).disable('x-powered-by').listen(3000, () => {console.log('Example app listening on port 3000!')})

复制

并给出以下示例网页(index.html):

<!DOCTYPE html>
<html><head><script>async function getRequest() {const response = await fetch('http://localhost:3000/asdf')const text = await response.text()alert(text)}async function postRequest(message) {const response = await fetch('http://localhost:3000/asdf',{method: 'post',body: { message },})const text = await response.text()alert(text)}</script>
</head><body><button onclick="getRequest()">Trigger GET request</button><br /><button onclick="postRequest('trigger1')">Trigger POST request (body 1)</button><br /><button onclick="postRequest('trigger2')">Trigger POST request (body 2)</button>
</body></html>

复制

安装NodeJS、Express并启动JavaScript应用程序。在浏览器中打开网页。尝试几种不同的方案来测试浏览器行为:

每次单击"Trigger GET request“时都会显示相同的" count”(HTTP高速缓存works).

  • Clicking "Trigger POST request“每次都会触发不同的计数(用于POST的HTTP高速缓存不会work).

  • Clicking "Trigger GET request”、"Trigger GET request“和"Trigger GET request”显示POST请求使GET请求的cache.

  • Clicking "Trigger POST request“无效然后单击"Trigger GET request”则显示浏览器不会为后续GET请求高速缓存POST请求,即使这是
  • 允许的。

这表明,即使您可以设置Cache-ControlContent-Location响应头,也无法让浏览器缓存HTTP POST请求。

我必须遵循RFC吗?

浏览器行为是不可配置的,但如果您不是浏览器,则不必受RFC规则的约束。

如果您正在编写应用程序代码,没有什么可以阻止您显式缓存POST请求(伪代码):

if (cache.get('hello')) {return cache.get('hello')
} else {response = post(url = 'http://somewebsite/hello', request_body = 'world')cache.put('hello', response.body)return response.body
}

复制

CDN、代理和网关也不必遵循RFC。例如,如果您使用Fastly作为您的CDN,Fastly允许您将custom VCL逻辑写入cache POST requests。

我应该缓存POST请求吗?

POST请求是否应该缓存取决于上下文。

例如,您可以使用POST查询Elasticsearch或GraphQL,其中您的底层查询是幂等的。在这些情况下,缓存响应可能有意义,也可能没有意义,具体取决于用例。

在RESTful应用程序接口中,POST请求通常创建一个资源,不应该被缓存。这也是RFC对POST的理解,它不是一个幂等操作。

GraphQL

如果您使用的是GraphQL,并且需要跨CDN和浏览器进行HTTP缓存,请考虑使用GET method而不是POST发送查询是否符合您的要求。需要注意的是,不同的浏览器和CDN可能有不同的URI长度限制,但是操作安全列表(查询白名单)作为面向外部的生产GraphQL应用程序的最佳实践,可以缩短URI。

相关文章:

是否可以在HTTP中缓存POST方法

如果您想知道是否可以缓存post请求&#xff0c;并尝试研究该问题的答案&#xff0c;那么您很可能不会成功。当搜索“缓存post请求”时&#xff0c;第一个结果是这个StackOverflow问题。 答案是令人困惑的&#xff0c;包括缓存应该如何工作&#xff0c;缓存如何根据RFC工作&…...

Xilinx 7系列FPGA配置(ug470)

Xilinx 7系列FPGA配置&#xff08;ug470&#xff09; 配置模式串行配置模式接口从-连接方式主-连接方式串行菊花链&#xff08;非同时配置&#xff09;串行配置&#xff08;同时配置&#xff09;时序 主SPI配置模式SPIx1/x2 连接图SPIx1模式时序SPIx4 连接图SPI操作指令操作fla…...

3分钟开通GPT-4

AI从前年12月份到现在已经伴随我们一年多了&#xff0c;还有很多小伙伴不会开通&#xff0c;其实开通很简单&#xff0c;环境需要自己搞定&#xff0c;升级的话就需要一张visa卡&#xff0c;办理visa卡就可以直接升级chatgptPLSU 一、虚拟卡支付 这种方式的优点是操作简单&…...

Easticsearch性能优化之索引优化

Easticsearch性能优化之索引优化 一、合理的索引设计二、合理的分片和副本三、合理的索引设置 对于性能优化&#xff0c;Elasticsearch&#xff08;以下简称ES&#xff09;的索引优化是提高性能的关键因素之一。合理的设计索引&#xff0c;合理的分片和副本以及合理的缓存设置等…...

安装mysql-8.0.30-winx64(windows 64位)

1.下载 1.1下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 2 .下载后解压缩目标文件 2.1之后在根目录下新建my.ini文件,并创建文件夹data &#xff08;新解压的文件没有my.ini文件&#xff0c;需自行创建 复制以下代码到my.ini文件 以下代码除安装目录和数据的…...

ios xcode 15 PrivacyInfo.xcprivacy 隐私清单

1.需要升级mac os系统到13 兼容 xcode 15.1 2.升级mac os系统到14 兼容 xcode 15.3 3.选择 New File 4.直接搜索 privacy 能看到有个App Privacy 5.右击Add Row 7.直接选 Label Types 8.选中继续添加就能添加你的隐私清单了 苹果官网文档Describing data use in privacy man…...

【物联网】-智能社会的分类

万物感知 感知物理世界&#xff0c;变成数字信号 &#xff08;温度、空间、触觉、嗅觉、听觉、视觉&#xff09; 万物互联 将数据变成online&#xff0c;使智能化 &#xff08;宽联接、广联接、多联接和深联接&#xff09; 万物智能 基于大数据和人工智能的应用 &#…...

Django高级之-cookie-session-token

Django高级之-cookie-session-token 发展史 1、很久很久以前&#xff0c;Web 基本上就是文档的浏览而已&#xff0c; 既然是浏览&#xff0c;作为服务器&#xff0c; 不需要记录谁在某一段时间里都浏览了什么文档&#xff0c;每次请求都是一个新的HTTP协议&#xff0c; 就是请…...

【Prometheus】k8s集群部署node-exporter

​ 目录 一、概述 1.1 prometheus简介 1.2 prometheus架构图 1.3 Exporter介绍 1.4 监控指标 1.5 参数定义 1.6 默认启用的参数 1.7 prometheus如何收集k8s/服务的–三种方式收集 二、安装node-exporter组件 【Prometheus】概念和工作原理介绍-CSDN博客 【云原生】ku…...

2024年k8s最新版本安装教程

k8s安装教程 1 k8s介绍2 环境搭建2.1 主机准备2.2 主机初始化2.2.1 安装wget2.2.2 更换yum源2.2.3 常用软件安装2.2.4 关闭防火墙2.2.5 关闭selinux2.2.6 关闭 swap2.2.7 同步时间2.2.8 修改Linux内核参数2.2.9 配置ipvs功能 2.3 容器安装2.3.1 设置软件yum源2.3.2 安装docker软…...

Gin 获取请求参数

POST 请求参数 Gin 获取Post请求URL参数有三种方式 func (c *Context) PostForm(key string) string func (c *Context) DefaultPostForm(key, defaultValue string) string func (c *Context) GetPostForm(key string) (string, bool)大多数情况下使用的是application/x-www…...

安卓 Kotlin 面试题 31-40

&#x1f525; 31、简述Kotlin 中的内联类&#xff0c;我们什么时候需要&#xff1f;&#x1f525; 有时&#xff0c;业务逻辑需要围绕某种类型创建包装器。 但是&#xff0c;由于额外的堆分配&#xff0c;它会引入运行时开销。 此外&#xff0c;如果包装的类型是原始类型&…...

【洛谷千题详解】P1613 跑路

目录 题目总览 题目描述 输入格式 输出格式 思路分析 AC代码 题目总览 题目描述 小 A 的工作不仅繁琐&#xff0c;更有苛刻的规定&#xff0c;要求小 A 每天早上在 6:00 之前到达公司&#xff0c;否则这个月工资清零。可是小 A 偏偏又有赖床的坏毛病。于是为了保住自己的…...

如何定义resultType和resultMap,它们之间的区别是什么?解释一下<parameterType>的作用和用法。

在MyBatis中&#xff0c;resultType和resultMap都用于将数据库查询结果映射到Java对象&#xff0c;但它们在使用方式和灵活性上有一些区别。 resultType resultType是一个简单的类型别名&#xff0c;它用于指定查询结果应该映射到的Java类型。当数据库表中的列名和Java对象的属…...

Docker:部署微服务集群

1. 部署微服务集群 实现思路&#xff1a; ① 查看课前资料提供的cloud-demo文件夹&#xff0c;里面已经编写好了docker-compose文件 ② 修改自己的cloud-demo项目&#xff0c;将数据库、nacos地址都命名为docker-compose中的服务名 ③ 使用maven打包工具&#xff0c;将项目…...

傅里叶变换pytorch使用

参考视频&#xff1a;1 傅里叶变换原理_哔哩哔哩_bilibili 傅里叶变换是干嘛的&#xff1a; 傅里叶得到低频、高频信息&#xff0c;针对低频、高频处理能够实现不同的目的。 傅里叶过程是可逆的&#xff0c;图像经过傅里叶变换、逆傅里叶变换后&#xff0c;能够恢复到原始图像…...

LeetCode104 二叉树的最大深度

题目 给定一个二叉树 root &#xff0c;返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a;root [1,null,…...

使用Spring的AOP

使用Spring的AOP 一、AOP 的常用注解1.切面类Aspect2.Pointcut3.前置通知Before4.后置通知AfterReturning5.环绕通知Around6.异常通知AfterThrowing7.最终通知After8.切面顺序Order9.启用自动代理EnableAspectJAutoProxy 二、AOP注解方式开发三、AOP 全注解开发四、基于XML配置…...

爬虫之矛---JavaScript基石篇3<JavaScript构造函数的内部机制和应用(2)>

前言: 继续上一篇https://blog.csdn.net/m0_56758840/article/details/136592611 正文: 1.ES6中的类和构造函数的对应关系 A. 介绍ES6引入的类的概念和语法糖 类的概念&#xff1a; ES6引入了类&#xff08;class&#xff09;的概念&#xff0c;类是一种抽象的数据类型&…...

_note_05

1.说一说什么是函数重载&#xff1f; 函数签名相同除了 形参不同数据类型 函数签名相同除了 形参不同个数 2.void关键字的作用&#xff1f;返回值是void &#xff0c;可以写return 吗&#xff1f; 函数无返回&#xff0c;使用void修饰; 可以只使用return使函数结束; 3.按要…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...