매우 간단한 캐싱 의미론을 사용하면 매개 변수가 동일하고 URL이 동일하면 적중합니다. 가능합니까? 추천?
답변
섹션 9.5 (POST) 의 해당 RFC 2616 을 사용하면 적절한 헤더를 사용하는 경우 POST 메시지 에 대한 응답 을 캐싱 할 수 있습니다.
응답에 적절한 Cache-Control 또는 Expires 헤더 필드가 포함되어 있지 않으면이 방법에 대한 응답을 캐시 할 수 없습니다. 그러나 303 (기타 참조) 응답을 사용하여 사용자 에이전트가 캐시 가능한 자원을 검색하도록 지시 할 수 있습니다.
동일한 RFC는 섹션 13 (HTTP에서 캐시)에서 명시 적으로 POST 요청 후 캐시가 해당 엔티티를 무효화해야 함을 명시합니다 .
일부 HTTP 메소드는 캐시가 엔티티를 무효화하도록해야합니다. 이는 Request-URI 또는 Location 또는 Content-Location 헤더 (있는 경우)에 의해 참조되는 엔티티입니다. 이러한 방법은 다음과 같습니다.
- PUT - DELETE - POST
이러한 사양이 어떻게 의미있는 캐싱을 허용 할 수 있는지는 확실하지 않습니다.
이것은 또한 RFC 2616을 폐지하는 RFC 7231 (4.3.3 절) 에 반영되고 더 명확 해졌다 .
POST 요청에 대한 응답은
명시 적 최신 정보가 포함 된 경우에만 캐시 할 수 있습니다 ([RFC7234]의 4.2.1 절 참조).
그러나 POST 캐싱은 널리 구현되지 않았습니다. 오리진 서버가 클라이언트가 나중에 GET에 의해 재사용 될 수있는 방식으로 POST 결과를 캐시 할 수 있기를 원하는 경우, 오리진 서버는 결과와 Content-Location을 포함하는 200 (OK) 응답을 보낼 수 있습니다. POST의 유효 요청 URI와 동일한 값을 가진 헤더 필드 (3.1.4.2 단원)
이에 따라, 캐시 된 POST의 결과 (이 능력이 서버에 의해 표시되는 경우)는 동일한 URI에 대한 GET 요청의 결과로서 후속 적으로 사용될 수있다.
답변
RFC 2616 섹션 9.5에 따르면 :
“응답에 적절한 Cache-Control 또는 Expires 헤더 필드가 포함되어 있지 않는 한 POST 방법에 대한 응답은 캐시 할 수 없습니다.”
예, POST 요청 응답을 적절한 헤더와 함께 도착한 경우에만 캐시 할 수 있습니다. 대부분의 경우 응답을 캐시하고 싶지 않습니다. 그러나 서버에 데이터를 저장하지 않는 경우와 같은 일부 경우에는 전적으로 적합합니다.
그러나 현재 Firefox 3.0.10을 포함한 많은 브라우저는 헤더에 관계없이 POST 응답을 캐시하지 않습니다. IE는 이런 점에서보다 현명하게 행동합니다.
이제 RFC 2616 S에 대한 혼란을 해결하고 싶습니다. 13.10. URI의 POST 메소드는 여기에 언급 된대로 “캐싱 할 자원을 무효화”하지 않습니다. 캐시 제어 헤더가 더 오래 지속되는 신선도를 표시하더라도 이전에 캐시 된 해당 버전의 URI를 무효로 만듭니다.
답변
사무용 겉옷:
기본적으로 POST는 dem 등원 작업이 아닙니다 . 따라서 캐싱에 사용할 수 없습니다. GET은 dem 등원 작업이어야하므로 캐싱에 일반적으로 사용됩니다.
HTTP 1.1 RFC 2616 S. 9.1 섹션 9.1을 참조하십시오 .
GET 메소드의 의미 이외의 것 :
POST 메소드 자체는 의미 적으로 자원에 무언가를 게시하기위한 것입니다. POST를 캐시 할 수 없습니다. 한 번 대 두 번 대 세 번 작업을 수행하면 매번 서버 리소스가 변경되기 때문입니다. 각 요청은 중요하며 서버로 전달되어야합니다.
PUT 메소드 자체는 의미 상 자원을 넣거나 작성하기위한 것입니다. dem 등원 작업이지만 그 동안 DELETE가 발생할 수 있으므로 캐싱에 사용되지 않습니다.
DELETE 메서드 자체는 의미 상 리소스를 삭제하기위한 것입니다. dem 등원 작업이지만 그 동안 PUT이 발생할 수 있기 때문에 캐싱에 사용되지 않습니다.
클라이언트 측 캐싱과 관련하여 :
웹 브라우저는 이전 POST 작업의 응답이 있더라도 항상 요청을 전달합니다. 예를 들어 며칠 간격으로 gmail로 이메일을 보낼 수 있습니다. 제목과 본문은 같을 수 있지만 두 이메일을 모두 보내야합니다.
프록시 캐싱과 관련하여 :
메시지를 서버로 전달하는 프록시 HTTP 서버는 GET 또는 HEAD 요청 외에는 아무것도 캐시하지 않습니다.
서버 캐싱과 관련하여 :
기본적으로 서버는 캐시 확인을 통해 POST 요청을 자동으로 처리하지 않습니다. 물론 POST 요청을 응용 프로그램이나 추가 기능으로 보낼 수 있으며 매개 변수가 같을 때 읽은 자체 캐시를 가질 수 있습니다.
자원 무효화 :
당좌 2616 S. 13.10 HTTP 1.1 RFC를 POST 메서드 캐싱을위한 리소스를 무효화해야한다고 쇼.
답변
POST 응답을 캐시하는 경우 웹 애플리케이션의 지시에 따라야합니다. 이는 “응답에 적절한 Cache-Control 또는 Expires 헤더 필드가 포함되어 있지 않으면이 방법에 대한 응답을 캐싱 할 수 없습니다”라는 의미입니다.
POST의 결과가 dem 등원인지 아닌지를 아는 응용 프로그램이 필요하고 적절한 캐시 제어 헤더를 첨부할지 여부를 결정한다고 안전하게 가정 할 수 있습니다. 캐싱이 허용되는 헤더가있는 경우 애플리케이션은 실제로 POST가 슈퍼 GET임을 알려줍니다. POST 사용은 dem 등원 (imdempotent) 작업을 수행하는 데 필요한 불필요하고 관련이없는 (URI를 캐시 키로 사용하는) 데이터로 인해 필요했습니다.
이 가정에 따라 다음과 같은 GET이 캐시에서 제공 될 수 있습니다.
캐싱 가능 및 캐싱 불가능 POST 응답을 구별하기 위해 필요하고 올바른 헤더를 첨부하지 못한 응용 프로그램은 유효하지 않은 캐싱 결과에 결함이 있습니다.
즉, 캐시에 도달하는 각 POST는 조건부 헤더를 사용하는 유효성 검사가 필요합니다. 이는 오브젝트의 수명이 만료 될 때까지 POST 결과가 요청에 대한 응답에 반영되지 않도록 캐시 컨텐츠를 새로 고치기 위해 필요합니다.
답변
Mark Nottingham은 POST 응답을 캐시 할 수있을 때 분석했습니다. 캐싱을 활용하려는 후속 요청은 GET 또는 HEAD 요청이어야합니다. http 의미론 참조
POST는 100에서 99 번의 식별 된 상태를 다루지 않습니다. 그러나 한 가지 경우가 있습니다. 서버가 요청 URI와 동일한 Content-Location 헤더를 설정하여이 POST 응답이 URI의 표현이라고 말하는 데 방해가되는 경우. 이런 경우 POST 응답은 동일한 URI에 대한 GET 응답과 같습니다. 캐시하고 재사용 할 수 있지만 향후 GET 요청에만 사용할 수 있습니다.
답변
게시 요청을 캐시하고 해당 질문에 대한 답변을 조사 할 수 있는지 궁금하다면 성공하지 못할 것입니다. “캐시 게시 요청”을 검색 할 때 첫 번째 결과는이 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
요청을 캐싱하지 않고 리소스를 캐싱하고 있습니다.
POST 응답 본문은 동일한 리소스에 대한 후속 GET 요청에 대해서만 캐시 될 수 있습니다. 본문이 나타내는 자원을 통신하도록 POST 응답에서 Location
또는 Content-Location
헤더를 설정하십시오 . 따라서 POST 요청을 캐시하는 기술적으로 유효한 유일한 방법은 동일한 GET에 대한 후속 GET입니다.
정답은 둘 다입니다.
- “예, RFC를 사용하면 후속 GET에 대한 POST 요청을 동일한 리소스에 캐시 할 수 있습니다.”
- “아니요. POST는 dem 등원이 아니며 서버를 통해 작성되어야하므로 RFC는 후속 POST에 대한 POST 요청을 캐시 할 수 없습니다.”
RFC를 통해 동일한 리소스에 대한 요청을 캐싱 할 수 있지만 실제로 브라우저와 CDN은이 동작을 구현하지 않으며 POST 요청을 캐시 할 수 없습니다.
출처 :
- https://tools.ietf.org/html/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 = 0
app
.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 애플리케이션을 시작하십시오. 브라우저에서 웹 페이지를여십시오. 몇 가지 시나리오를 시도하여 브라우저 동작을 테스트하십시오.
- “트리거 GET 요청”을 클릭하면 매번 동일한 “카운트”가 표시됩니다 (HTTP 캐싱 작동).
- “Trigger POST request”를 클릭하면 매번 다른 카운트가 트리거됩니다 (POST에 대한 HTTP 캐싱이 작동하지 않음).
- “Trigger GET request”, “Trigger POST request”및 “Trigger GET request”를 클릭하면 POST 요청이 GET 요청의 캐시를 무효화 함을 표시합니다.
- “Trigger POST request”를 클릭 한 다음 “Trigger GET request”를 클릭하면 RFC에서 허용하더라도 브라우저가 후속 GET 요청에 대한 POST 요청을 캐시하지 않습니다.
이는 Cache-Control
및 Content-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를 따를 필요는 없습니다. 예를 들어 CDN으로 Fastly를 사용하는 경우 POST 요청 을 캐시하는 사용자 지정 VCL 논리를 Fastly로 작성할 수 있습니다 .
POST 요청을 캐시해야합니까?
POST 요청을 캐시해야하는지 여부는 컨텍스트에 따라 다릅니다.
예를 들어, 기본 쿼리가 dem 등원 인 POST를 사용하여 Elasticsearch 또는 GraphQL을 쿼리 할 수 있습니다. 이러한 경우 사용 사례에 따라 응답을 캐시하는 것이 합리적 일 수도 있고 그렇지 않을 수도 있습니다.
RESTful API에서 POST 요청은 일반적으로 리소스를 생성하므로 캐시해서는 안됩니다. 이것은 또한 POST가 dem 등원이 아니라는 RFC의 이해입니다.
GraphQL
GraphQL을 사용하고 CDN 및 브라우저에서 HTTP 캐싱이 필요한 경우 GET 메소드를 사용하여 쿼리를 보내는 것이 POST 대신 요구 사항을 충족하는지 고려하십시오 . 주의 사항에 따라 브라우저와 CDN마다 URI 길이 제한이 다를 수 있지만 외부 연결 프로덕션 GraphQL 앱의 모범 사례 인 작업 허용 목록 (쿼리 화이트리스트)은 URI를 단축 할 수 있습니다.
답변
실제로 사이트의 데이터를 변경하지 않는 것이면 GET 요청이어야합니다. 양식 인 경우에도 가져 오기 요청으로 설정할 수 있습니다. 다른 사람들이 지적했듯이 POST의 결과를 캐시 할 수는 있지만 정의에 의한 POST가 데이터를 변경하기 때문에 의미 론적으로 의미가 없습니다.