Image File을 업로드 하고, 그 Image를 Front에서 봐야 합니다.
Image Url를 제공하는 것 말고, jwt token까지 처리 후 사용할 수 있는 환경에 대해 고민했었습니다.
url로 직접 접근 하지 않고, 로그인 후 받아두었던 Token으로 인증하면서,
이미지를 보게 하는 방법이 무엇일까?하는
1. url query param에 넣을까?
http://url?token={{token}}
2. token 보여주기 싫은데 어쩌지
최종으로 2번을 선택했습니다.
So API에 get router를 만든 후 Front에서 api 호출 후 Image를 blob으로 받게 하는 것이었습니다.
API 예제
const dir = path.join(__dirname, '../public');
const location = `images/${userNo}/${fileNo}/test.jpg`;
res.set('Content-Type', 'image/jpg');
res.sendFile(`${dir}/${location}`);
API 에서 sendFile로 내려줍니다.
Front
// angular-cli
ng g p wild-animals
wild-animals pipe를 만들어줍니다.
// awesome pipe transform
transform(value: string): any {
if (this.util.isNull(value)) {
return;
}
this.http.get(value, {responseType: 'blob'}).toPromise().then(blob => {
this.fileResource = this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(blob));
return this.fileResource;
});
}
responseType: 'blob' 설정에 따라
result는 blob으로 떨어졌고,
URL.createObjectURL(blob)
blob url을 만듭니다.
unsafe 경고가 나오니
this.sanitizer.bypassSecurityTrustUrl
DomSanitizer 를 사용하여 해결해줍니다.
여기까지는 DomSanitizer만 도움을 받았고, 목표했던 개발입니다.
<img [src]="imageUrl | wildAnimals" alt="">
예상과 다르게 동작하지 않습니다.
base64 변환해서 처리도 해보고, 반나절을 꼬박 쏟았지만
결과는 unknown || undefined 였습니다.
혹시나 싶어 component로 로직을 옮겼더니 잘 됩니다.
코드의 문제는 아니었단 말이죠.
(더러운 세상..)
지금 다시 보니 애초에 안될만도 했던 것 같습니다.
그래서 폭풍 구글링 후, async 를 활용할 수 있단 걸 감지했습니다.
야수의 심장으로 빠이쁘를 고칩니다.
다시 pipe를 수정합니다.
빌어먹을 빠이쁘!
// wild-animals pipe transform
return this.http.get(value, { responseType: 'blob' }).toPromise()
.then(blob => this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(blob)));
<img [src]="imageUrl | wildAnimals | async" alt="">
Angular pipe
Description
The async pipe subscribes to an Observable or Promise and returns the latest value it has emitted. When a new value is emitted, the async pipe marks the component to be checked for changes. When the component gets destroyed, the async pipe unsubscribes automatically to avoid potential memory leaks.
영어를 잘들 하시겠지만..
pipe transform에서 async await를 써도 안잡혔고,
async pipe를 통해서 잡을 수 있었던 것 같습니다.
이번 경험을 통해 얻은 것은 pipe에서 http 통신 후 결과를 받을 때, Observable or Promise를 통해 async pipe 처리해야 한다는 것입니다.
async pipe 안붙이고 쓰고 싶었지만 더는 아이디어가 없기에 마무리합니다.
이렇게 저는 마음에 드는 좋은 pipe가 생겼습니다.
(뭐 물론 Angular 안쓰고, React, Vue 쓰시겠지만!)