전단 전역 교체 이미지 서비스 cdn 솔 루 션
17194 단어 웹 공학 화
주로 우리 제품 에서 의존 하 는 특정한 cdn, 예 를 들 어 이미지 서비스 가 오프라인 상태 에서 이런 상황 을 해결 하고 처리 하 는 몇 가지 방안 이 있 는 지 소개 합 니 다.수 동 코드 층 교체, 전역 이상 모니터링, 스타일 이미지 자원 처리, nginx 맵 수정 과 serviceworker 의 여러 가지 방법 을 비교 합 니 다.
해결 방안
우선, 하나의 cdn 서비스 가 곧 오프라인 된다 면, 우 리 는 자원 을 다른 cdn 으로 대량으로 유도 해 야 합 니 다.자원 자체 가 존재 하지 않 는 다 면 이 문 제 를 해결 할 방법 도 없다.
수 동 코드 교체
cdn 서비스의 그림 은 코드 에서 url 의 인용 을 지정 합 니 다.
예 를 들 면:
<img class="f-fl" src="http://img1.ph.126.net/fJDziquhVcOupiyTYX9MDg==/3359685322118823946.png">
프로젝트 유지보수 성 이 높 으 면 접 두 사 를 전역 통일 변수 로 설정 할 수 있 습 니 다.
우리 가 오프라인
img1.ph.126.net
을 하려 고 할 때 img-ph-mirror.nosdn.127.net
로 넘 어 갈 때.우 리 는 전역 코드 를 교체 하 는 방식 을 사용 할 수 있다.이런 방법의 단점 은 다음 과 같다.
1. 만약 에 전기 개발 자의 유지 의식 이 떨 어 지면 모든 위치 에서 수 동 으로 수정 하고 관련 테스트 를 해 야 하 며 작업량 이 많다.
2. 코드 차원 만 수 정 했 기 때문에 데이터베이스 에 있 는 데 이 터 를 수정 할 수 없고 인터페이스 에서 돌아 오 는 동적 데이터 로드 자원 에 접근 할 수 없습니다.
전역 이상 모니터링
전단 전역 이상 모니터링 에서 불 러 오 는 데 실패 한 그림 을 가 져 와 교체 하고 dom 을 수 동 으로 조작 하여 그림 의 교 체 를 완성 합 니 다.
핵심 논 리 는 다음 과 같다.
window.addEventListener(
"error",
function(e) {
//
var target = e.target;
if (
target &&
target.tagName &&
target.tagName.toUpperCase() === "IMG" &&
//
_isImgph.test(target.src)
) {
//
var newSrc = scaleImage(e.target.src);
//
console.warn("img :" + e.target.src);
//
e.target.src = newSrc;
}
},
true
);
이런 방식 은 데이터베이스 와 인터페이스 에서 오 는 동적 데 이 터 를 해결 할 수 있 을 것 같다.
그러나 그 결함 도 뚜렷 하 다.
1. 자원 로드 순서 문제 가 존재 합 니 다. 만약 에 자원 이 캡 처 되 지 않 은 데 이 터 를 먼저 불 러 오 면 효력 을 잃 습 니 다.해결 하려 면 이 논 리 를 맨 머리 에 넣 어야 한다.
2. js 는 js 의 그림 자원 을 감청 하 는 데 실 패 했 습 니 다.스타일 에 있 는 자원 을 불 러 오 는 데 실 패 했 을 경우, 이 방안 은 아무런 효과 가 없습니다.
스타일 중 이미지 모니터링
스타일 에 있 는 이미지 자원 모니터링 은 비교적 번 거 로 운 문제 입 니 다. 현재 브 라 우 저 는 해당 하 는 API 를 제공 하지 않 아 캡 처 에 실 패 했 기 때 문 입 니 다.
그러나 hack 스타일 의 해결 방법 도 있 습 니 다. 여 기 는 라 이브 러 리 이미지 sloaded 의 사고방식 을 사용 해 야 합 니 다.그 소스 코드 분석 은 imagesloaded 소스 코드 분석 을 참조 할 수 있다.
핵심 소스 코드 는 다음 과 같 습 니 다.
//
ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
var style = getComputedStyle( elem );
if ( !style ) {
// Firefox returns null if in a hidden iframe https://bugzil.la/548397
return;
}
// get url inside url("...")
var reURL = /url\((['"])?(.*?)\1\)/gi;
var matches = reURL.exec( style.backgroundImage );
while ( matches !== null ) {
var url = matches && matches[2];
if ( url ) {
// url
this.addBackground( url, elem );
}
matches = reURL.exec( style.backgroundImage );
}
};
//
function Background( url, element ) {
this.url = url;
this.element = element;
// new Image js 。
this.img = new Image();
}
// url
Background.prototype.check = function() {
this.img.addEventListener( 'load', this );
this.img.addEventListener( 'error', this );
this.img.src = this.url;
// check if image is already complete
var isComplete = this.getIsImageComplete();
if ( isComplete ) {
this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
this.unbindEvents();
}
};
주요 사 고 는 등 록 된 dom 에 따라 getComputed Style () 으로 노드 의 스타일 을 가 져 온 다음 에 new Image 를 통 해 이상 을 불 러 올 지 여 부 를 판단 하 는 것 입 니 다.이상 하면 수 동 으로 dom 스타일 을 맞 춥 니 다.
이런 방법의 단점 은:
1. dom 목록 을 등록 해 야 합 니 다. 비록 우 리 는
document.all
을 통 해 모든 dom 을 얻 을 수 있 지만 이러한 성능 은 문제 가 될 수 있 습 니 다.nginx
이런 방법 은 마 땅 히 일 로 영일 해 야 한다.서버 차원 에서 모두 차단 합 니 다.
그러나 이런 방법 은 몇 가지 장면 이 적용 되 지 않 는 다.
1. 교체 해 야 할 cdn 이 한 쌍 이 많 을 때 직접 수정 할 수 없습니다.예 를 들 어 왕 이 클 라 우 드 수업 은
img1.ph.126.net
- > img-ph-mirror.nosdn.127.net
가 필요 하고 왕 이 콜 라 는 img1.ph.126.net
- > kaola-mirror.nosdn.127.net
가 필요 할 때 직접 수정 할 수 없다 img1.ph.126.net
.2. 교체 규칙 이 비교적 복잡 할 때 공사 내 업무 util 방법 에 의존 해 야 할 때.
serviceworker 전단 전역 차단
serviceworker 를 이용 하여 전역 요청 을 차단 할 수 있 는 기능 을 사용 하여 전단 에서 전역 차단 과 교 체 를 실현 합 니 다.
서비스 워 커 에 대한 소 개 는 더 이상 반복 되 지 않 습 니 다.클 라 우 드 교실 의 첫 페이지 최 적 화 를 개발 할 때 이미 관련 정리 서비스 워 커 사용 실천 이 있 었 다.
핵심 논 리 는 다음 과 같다.
self.addEventListener("fetch", function(event) {
if (
// cdn
(_isImgph.test(event.request.url) ||
_isImgSize.test(event.request.url)) &&
event.request.method === "GET"
) {
//
var url = scaleImage(event.request.url);
// request
var req = new Request(url);
event.respondWith(
fetch(req).then(function(response) {
return response;
})
);
}
});
이런 방법의 단점 은:
1. 호환성 문 제 는 상대 적 으로 새로운 특성 이기 때문에 ie 전선 과 이전 버 전의 모 바 일 wap 는 지원 되 지 않 습 니 다.
2. 도 메 인 을 뛰 어 넘 을 수 없 기 때문에 다 중 도 메 인 이름 제품 은 각 도 메 인 에서 등록 해 야 합 니 다.
후기
필 자 는 결국 호환성 수요 와 급박 성 을 고려 해 서비스 워 커 의 방법 을 사용 했다.
더 좋 은 해결 방안 이 있 거나 제 가 고려 하지 못 한 문제 가 있 으 면 저 에 게 연락 하여 기술 을 교류 하 는 것 을 환영 합 니 다.
링크