iOS6의 사파리는, 기본적으로 POST 요청에 대한 응답을 캐싱한다.
여기서 치명적인 문제가 발생한다. 서버에서 요청의 대상이 되는 리소스가 갱신되었음에도 불구하고, 사파리는 캐시했던 이전 응답을 사용자에게 보여주게 될 수 있다.
문제가 발생하는지에 대한 테스트는 여기에서 해볼 수 있다. 이 테스트에서 브라우저는 두 번의 POST 요청을 서버에게 보내고 서버는 그 요청에 대해 각각 다른 응답을 한다. 그러나 iOS6의 사파리에서는 두 번 전부 같은 응답을 받게 될 것이다.
회피책
이 문제를 회피하는 두 가지 방법이 있다.
- 클라이언트 사이드: 캐시되지 않도록 query string에 매번 바뀌는 임의의 문자열(예: 현재 시각)을 붙인다.
- 서버 사이드: POST 요청에 대한 응답에, Pragma: no-cache 나 Cache-control: no-cache 를 명시해준다.
위 둘 중 하나만 적용해도 문제가 발생하지 않는다. 자세한 설명은 Guillermo Rauch의 ‘iOS6 AJAX 버그 이해하기‘를 보라.
누구의 잘못인가?
애플의 잘못이다. HTTP/1.1을 정의한 RFC 2616의 POST에 대한 설명을 읽어보면, POST 요청에 대한 응답은 기본적으로 캐시해서는 안됨을 알 수 있다. 응답에 Cache-Control 이나 Expires 헤더가 정의되어있는 경우에만 캐시를 할 것인지에 대해 고려할 수 있다.
자세한 것은 HTTPbis Working Group의 의장인 Mark Nottingham이 이번 건에 대해 포스팅한 ‘POST 캐싱‘을 읽어보라.
“iOS6 사파리의 POST 캐싱 버그에 대해”에 대한 1개의 생각