是否可以在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://www.mzph.cn/news/736305.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RDD算子介绍(二)

1. coalesce 用于缩减分区&#xff0c;减少分区个数&#xff0c;减少任务调度成本。 val rdd : RDD[Int] sc.makeRDD(List(1, 2, 3, 4), 4) val newRDD rdd.coalesce(2) newRDD.saveAsTextFile("output") 分区数可以减少&#xff0c;但是减少后的分区里的数据分布…

代码随想录算法训练营Day41 ||leetCode 0-1背包问题 || 416. 分割等和子集

0-1背包问题 dp[i][j]的含义&#xff1a;从下标为[0-i]的物品里任意取&#xff0c;放进容量为j的背包&#xff0c;价值总和最大是多少。 那么可以有两个方向推出来dp[i][j]&#xff0c; 不放物品i&#xff1a;由dp[i - 1][j]推出&#xff0c;即背包容量为j&#xff0c;里面不放…

02-app端文章查看,静态化freemarker,分布式文件系统minIO-黑马头条

app端文章查看&#xff0c;静态化freemarker,分布式文件系统minIO 1)文章列表加载 1.1)需求分析 文章布局展示 1.2)表结构分析 ap_article 文章基本信息表 ap_article_config 文章配置表 ap_article_content 文章内容表 三张表关系分析 1.3)导入文章数据库 1.3.1)导入数据…

详解@Configuration

简介 Configuration注解用于标识一个类作为Spring的配置类&#xff0c;从而允许使用纯Java代码的方式来定义Bean和Bean之间的依赖关系。 Configuration注解是Spring框架中非常核心的一个功能&#xff0c;它提供了一种替代XML配置文件的方法。通过该注解&#xff0c;开发人员可…

ROS2从入门到精通0-2:ROS2简介、对比ROS1与详细安装流程

目录 0 专栏介绍1 什么是机器人操作系统&#xff1f;2 ROS的发展历程3 ROS2与ROS1的区别4 ROS2安装4.1 基本安装4.2 测试ROS24.2.1 测试一&#xff1a;发布者与订阅者4.2.2 测试二&#xff1a;海龟仿真器 5 常见问题 0 专栏介绍 本专栏旨在通过对ROS2的系统学习&#xff0c;掌…

信息系统项目管理师--成本管理

项⽬成本管理重点关注完成项⽬活动所需资源的成本&#xff0c;但同时也考虑项⽬决策对项⽬产品、服务或成果的使⽤成本、维护成本和⽀持成本的影响。不同的⼲系⼈会在不同的时间&#xff0c;⽤不同的⽅法 测算项⽬成本。 就某些项⽬&#xff0c;特别是⼩项⽬⽽⾔&#xff0c;成…

FocusVisualStyle通常是键盘焦点样式

设置了Button的FocusVisualSytle但是死活没有效果&#xff0c;查了一下这个是键盘焦点样式&#xff0c;摁下Tab键了才能让Button有焦点 <ButtonWidth"100"Height"30"FocusVisualStyle"{DynamicResource MyFocusVisual}">按钮1 </Butto…

VSCode报错:/bin/sh: python: command not found

背景 以前都是直接用txt写python&#xff0c;然后直接命令行运行。 这次涉及的代码较多&#xff0c;决定用编译器。 写好的一段python点击运行报错&#xff01; 问题描述 因为我本地安装的是python3&#xff0c;但是vscode用的是另一个路径的python&#xff0c;所以找不到 解决…

_note_04_02

1&#xff1a;输出1-20之间的奇数。 package _09142023.homework_04;import java.util.Scanner;/**** 输出1-20之间的奇数。**/ public class _07_1 {public static void main(String[] args) {System.out.println("1到20之间的奇数&#xff1a;");for (int i 1; i…

视觉语言处理:用Transformer桥接视觉与语言

引言 人工智能研究的前沿领域见证了显著的交叉融合。将计算机视觉和自然语言处理的领域融合&#xff0c;问题随之而来&#xff1a;AI能否直接从其视觉表现&#xff0c;即从原始像素中辨识和理解语言&#xff1f;在这篇博客中&#xff0c;我试图探究AI从图像中直接理解自然语言的…

在 Android 上恢复已删除文件的 5 种简单方法

您可能会因为意外删除、未完成的 Android 更新、手机意外关机等原因而丢失 Android 上的重要数据。新技术的发展使许多手机功能或程序能够从内部恢复丢失的数据。 在 Android 上恢复已删除文件的 5 种简单方法 然而恢复成功率的不确定性也成为人们克服数据丢失困境的重要考虑因…

Android14音频进阶:AudioTrack与AudioFlinger创建数据通道(五十八)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

子类和父类不在同一包中的继承性

不同包中的继承性 继承父类的protected 、public 成员变量 继承父类的 protected 、public 方法&#xff1b; 继承的成员或方法的 。 public class People { int age,leg 2,hand 2; public void showPeopleMess() { System.out.printf("%d岁&#xff0c;%d只脚,%d只手…

[Spring] IoC 控制反转和DI依赖注入和Spring中的实现以及常见面试题

目录 1. 什么是Spring 2.什么是IoC容器 3.通过实例来深入了解IoC容器的作用 3.1造一量可以定义车辆轮胎尺寸的车出现的问题 3.2解决方法 3.3IoC优势 4.DI介绍 5.Spring中的IoC和DI的实现 5.1.存对象 5.1.2 类注解 5.1.3 方法注解 5.2取对像 (依赖注入) 5.2.1.属性…

FPGA高端项目:FPGA基于GS2971的SDI视频接收+HLS多路视频融合叠加,提供1套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收转HDMI输出应用本方案的SDI接收图像缩放应用本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收HLS图像缩放Video Mixer多路视频拼接应用本方案的SDI接收OSD动态字符叠加…

护眼台灯怎么选比较好?明基、爱德华、书客护眼台灯硬核PK测评

现在不管是学生党学习阅读&#xff0c;还是办公族加班工作&#xff0c;都离不开一盏光源舒适的台灯&#xff0c;然而如今的台灯市场水实在太深的&#xff0c;各种网红、劣质产品混杂在其中&#xff0c;这类台灯往往采用劣质电源&#xff0c;其电源品质较差&#xff0c;导致输出…

开发指南002-前后端信息交互规范-返回值定义

public enum IOResultEnum {SUCCESS(88888888, "IOResult_88888888"),//操作成功ERROR(99999999, "IOResult_99999999"), //操作失败EXCEPTION(11111111, "IOResult_11111111"),//操作异常AUTHORIZATE_FAIL(9000,"IOResult_9000"),//没…

VUE3 显示Echarts百度地图

本次实现最终效果 技术基础以及环境要求 vue3 echarts 百度地图API 要求1&#xff1a; VUE3 环境搭建&#xff1a;https://blog.csdn.net/LQ_001/article/details/136293795 要求2&#xff1a; VUE3 echatrs 环境搭建:https://blog.csdn.net/LQ_001/article/details/1363…

Ps:画笔工具

画笔工具 Brush Tool是 Photoshop 中最常用的工具&#xff0c;可广泛地用于绘画与修饰工作之中。 快捷键&#xff1a;B ◆ ◆ ◆ 常用操作方法与技巧 1、熟练掌握画笔工具的操作对于使用其他工具也非常有益&#xff0c;因为 Photoshop 中许多与笔刷相关的工具有类似的选项和操…

docker一键安装debian/ubuntu桌面环境LXDE+VNC+Firefox

好处不用说&#xff0c;可以在linux服务器版本使用chrome和firefox浏览器&#xff0c;步骤如下&#xff1a; 1.拉取镜像 镜像大概有1.3G左右 docker pull dorowu/ubuntu-desktop-lxde-vnc 使用docker images 查看镜像id 2.运行容器 docker run -dit --name ubuntu -p 6080…