HTTP 접근 제어 (CORS)
Cross Origin Resource Sharing(CORS)
HTTP요청은 기본적으로 Cross-Site-HTTP Requests가 가능하다.
다시말하면, <img>
, <link>
, <script>
태그로 다른 도메인의 리소스를 가져오는 것이 가능하다.
그런데!
스크립트에서 생성된 Cross-Site HTTP Requests는 Same Origin Policy를 적용 받기 때문에 Cross-Site HTTP Requests가 불가능하다.
ajax가 많이 사용되면서 스크립트에서 생성되는 XMLHttpRequest
에 대해서도 Cross-Site HTTP Requests가 가능해야 한다는 요구가 많이 나왔고 W3C에서 CORS라는 이름의 권고안이 나왔다.
CORS 요청의 종류
- Simple
- Preflight
- Credential
- Non-Credential
브라우저가 요청 내용을 분석하여 4가지 방식 중 해당하는 방식으로 서버에 요청을 날린다.
실무에서..
얼마전 이미지의 다른 도메인에서 불러와서 켄버스에 그려 이미지의 픽셀값을 가져오는 일이 있었다.
이런 에러가 발생하였다.
처음에는 이미지 CORS 속성을 anonymous
로 지정을 했다.
img.crossOrigin = "anonymous";
그래도 계속되었다.
이미지가 저장되어 있는 서버에서 이미지를 보내줄 때 헤더에 crossOrigin내용을 첨부해서 보내주면 되지만, 현실적으로 불가능해 클라이언트 측에서 처리하기로 했고 아래와 같이 이미지를 DOM스토리지에 저장하고 DOM스토리지에서 이미지를 불러오는 방식으로 문제를 해결 했다.
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
<FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz?|webp)$">
SetEnvIf Origin ":" IS_CORS
Header set Access-Control-Allow-Origin "*" env=IS_CORS
</FilesMatch>
</IfModule>
</IfModule>
var img = new Image,
canvas = document.createElement("canvas"),
ctx = canvas.getContext("2d"),
src = "http://example.com/image"; // insert image url here
img.crossOrigin = "Anonymous";
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage( img, 0, 0 );
localStorage.setItem( "savedImageData", canvas.toDataURL("image/png") );
}
img.src = src;
// make sure the load event fires for cached images too
if ( img.complete || img.complete === undefined ) {
img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
img.src = src;
}
Browser compatibility
Chrom | Firefox | IE | Opera | Safari |
---|---|---|---|---|
13 | 8 | No support | No support | ? |