일반적으로 팀에는 Tencent의 gtimg.com 및 Baidu의 bdimg.com과 같은 정적 리소스를 배치하기 위한 특수 도메인 이름이 있거나 많은 팀이 Tencent Cloud 또는 Alibaba Cloud 서비스를 사용합니다.
기본 페이지의 도메인 이름이 다른 경우가 많습니다. 캔버스 이미지에 대해 getImageData() 또는 toDataURL() 작업을 수행해야 하는 경우 교차 도메인 문제가 발생하며 두 수준 이상의 교차 도메인 문제가 있습니다.
먼저, 첫 번째 단계에서 이미지 서버는 Access-Control-Allow-Origin 정보를 구성해야 합니다. 예를 들면 다음과 같습니다.
예를 들어, PHP는 응답 헤더 정보를 추가하고 * 와일드카드는 모든 도메인 이름이 허용됨을 나타냅니다.
헤더(액세스 제어-허용-원본: *);
또는 도메인 이름을 지정하세요.
헤더(액세스 제어-허용-원본: www.zhangxinxu.com);
현재 Chrome 브라우저에는 더 이상 Access-Control-Allow-Origin 관련 오류 메시지가 표시되지 않지만 다른 도메인 간 오류 메시지가 표시됩니다.
2. 캔버스 그림 getImageData 교차 출처 교차 도메인 문제크로스 도메인 이미지의 경우, 웹 페이지에 정상적으로 표시될 수 있는 한 캔버스의 drawImage() API를 사용하여 그릴 수 있습니다. 그러나 한 단계 더 나아가 getImageData() 메서드를 통해 이미지의 전체 픽셀 정보를 얻으려는 경우 오류가 발생할 수 있습니다.
예를 들어, github에서 자신의 아바타 사진 정보를 얻으려면 다음 코드를 사용하십시오.
var canvas = document.createElement('canvas');var context = canvas.getContext('2d');var img = new Image();img.onload = function () { context.drawImage(this, 0, 0) ; context.getImageData(0, 0, this.width, this.height);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
그 결과 Chrome 브라우저에 다음 오류가 표시됩니다.
포착되지 않은 DOMException: 'CanvasRenderingContext2D'에서 'getImageData'를 실행하지 못했습니다. 캔버스가 원본 간 데이터로 인해 오염되었습니다.
Firefox 브라우저 오류는 다음과 같습니다.
SecurityError: 작업이 안전하지 않습니다.
canvas.toDataURL() 메서드를 사용하면 다음과 같이 보고됩니다.
'HTMLCanvasElement'에서 'toDataURL' 실행 실패: 오염된 캔버스를 내보낼 수 없습니다.
이유는 실제로 도메인 간으로 인해 동일합니다.
그렇다면 이 문제를 해결할 수 있는 방법은 없을까?
crossOrigin 속성을 사용해 볼 수 있습니다.
3. HTML crossOrigin 속성은 리소스의 도메인 간 문제를 해결합니다.HTML5에서 일부 요소는 CORS(Cross-Origin Resource Sharing)(교차 원본 리소스 공유)를 지원하는 속성을 제공하며 이러한 요소에는 <img>, <video>, <script> 등이 포함되며 제공되는 속성 이름은 입니다. 크로스오리진 속성.
따라서 위의 크로스 도메인 문제는 다음과 같이 처리될 수 있습니다.
var canvas = document.createElement('canvas');var context = canvas.getContext('2d');var img = new Image();img.crossOrigin = '';img.onload = function () { context.drawImage (this, 0, 0); context.getImageData(0, 0, this.width, this.height);};img.src = 'https://avatars3.githubusercontent.com/u/496048?s=120&v=4';';
img.crossOrigin = ''만 추가하면 됩니다. 여기서 JS 코드는 빈 문자열을 설정하지만 작동하는 실제 속성 값은 익명입니다.
crossOrigin은 다음 두 가지 값을 가질 수 있습니다.
키워드 | 정의 |
---|---|
익명의 | 요소에 대한 교차 출처 리소스 요청에는 자격 증명 플래그를 설정할 필요가 없습니다. |
사용 자격 증명 | 요소에 대한 도메인 간 리소스 요청에는 자격 증명 플래그를 설정해야 합니다. 즉, 요청에 자격 증명이 필요합니다. |
그 중 crossOrigin의 속성 값이 use-credentials가 아닌 한, 'abc'와 같은 문자를 포함하여 빈 문자열을 포함한 모든 것이 익명으로 구문 분석됩니다.
예를 들어:
img.crossOrigin = 'abc';console.log(img.crossOrigin); // 결과는 'anonymous'입니다.
주목해야 할 또 다른 점은 crossOrigin 속성이 없고 crossOrigin=use-credentials를 설정하면 기본적으로 도메인 간 오류가 보고되지만 본질적으로 다르며 둘 사이에는 큰 차이가 있다는 것입니다.
크로스오리진 호환성IE11+(IE Edge), Safari, Chrome 및 Firefox 브라우저는 모두 이를 지원합니다. IE9 및 IE10은 아래 스크린샷과 같이 SecurityError를 보고합니다.
4. crossOrigin 속성이 크로스 도메인 리소스 문제를 해결할 수 있는 이유는 무엇입니까?crossOrigin=anonymous 다른 서버에 알리는 대신 익명이 아닌 정보를 가져올 필요가 없습니다. 예를 들어 쿠키는 현재 브라우저가 확실히 안전합니다.
옷을 가지러 다른 사람의 집에 가고 싶은 것처럼, crossOrigin=anonymous는 다른 사람에게 옷만 원하고 다른 것은 없다고 말하는 것과 다릅니다. 알려주지 않으면 상대방이 옷 속에 도청 장치나 물건을 넣을 수도 있어 안전하지 않을 수 있으며 브라우저에서 이를 차단합니다.
5. IE10 브라우저가 crossOrigin을 지원하지 않으면 어떻게 해야 합니까?이미지를 요청할 때 new Image()를 직접 사용하지 않고 ajax와 URL.createObjectURL() 메소드를 사용하여 국가를 저장합니다.
코드는 다음과 같습니다:
var xhr = new XMLHttpRequest();xhr.onload = function () { var url = URL.createObjectURL(this.response); var img = new Image() = function () { // 이 시점에서 img // ... code ... // 이미지를 사용한 후 메모리를 해제하는 것을 잊지 마세요. URL.revokeObjectURL(url) }; = url;};xhr.open('GET', url, true);xhr.responseType = 'blob';xhr.send();
이 방법은 IE10 브라우저에 적합할 뿐만 아니라 원래 crossOrigin을 지원했던 모든 브라우저에서도 지원됩니다.
Ajax 요청을 한 번만 더 하면 됩니다. 괜찮습니다!
실제로 IE 브라우저에서는 요청한 이미지가 수천 픽셀로 너무 크면 이미지가 블롭 크기 제한을 초과하는 것 같습니다.
6. 결론최근 직장에서 약간의 경험을 배웠는데, 비슷한 문제에 직면한 친구들에게 도움이 되기를 바랍니다. 또한 모든 사람들이 VeVb Wulin Network를 지지해주기를 바랍니다.