✅ 문제-해결
문제1. api get요청시 쿼리스트링 문자로 호출하면 에러나는 문제
처음엔 일단 통신이 잘 되는지만 확인해보려고 axios url에 파라미터를 쿼리스트링으로 직접 작성해줬다.
그런데 400 에러가 발생하였고, 이것 때문에 파라미터 값에 문제가 있는 줄 알아 애먹었다.
그러다 axios의 params로 파라미터를 담아줬더니 정상적으로 응답이 되었다.
결국 두 url 다 동일한 주소일텐데 왜 다른걸까 의문이다.
→ 두 url이 실제 api를 요청할 때 인코딩여부가 다른데 이게 영향이 있는 것 같다.
- params : 인코딩을 해준다. (axios 라이브러리에서 해주는듯)
- 쿼리스트링 : 인코딩 안해줌, 인코딩을 안하면 문제가 되는 문자열이 있어서 오류난 것 같음
(url주소에 backslash"\"가 여러 있었는데, 백슬래시는 url에 잘 안쓰는 것으로 알고있음)
→ fetch로 get요청시 쿼리스트링을 보낸다면, URLSearchParams 사용
- URLSearchParams 로 쿼리스트링 보내면 자동으로 인코딩됨
문제2. 브라우저에서 파일 다운되지 않는 문제
api통신으로 파일을 응답받았지만 그 뿐, 다운로드 파일을 사용자에게 보여지는 문제 발생.
[원인1] 응답 데이터는 문자열이였다.
→ responseType을 blob으로 붙여 dxf파일 형식의 응답을 받아야 했었다.
응답 결과 : Blob {size: 11111, type: 'application/octet-stream'}
(단순 객체처럼 보이지만 Blob는 생성자 함수고 인스턴스 객체인 것임)
→ 응답 데이터를 zip파일로 받을 땐 responseType을 arraybuffer 로 처리했음
[원인2] a태그를 이용하여 chrome에서 다운로드 팝업창 띄우도록 처리하여 해결
✅ 구현코드
axios({
url: "/download/file",
method: "GET",
params: {
format: "dxf",
layerName: "layer_name",
viewparams: `c_id:1;o_id:1,2,3,;r_id:40011;`
},
responseType: "blob" // 응답 타입을 blob로 지정
})
.then((response) => {
if (response.status === 200) {
const blobData = response.data; // 응답 데이터는 blob 이다.// Blob {size: 1818717, type: 'application/octet-stream'}
const blobUrl = URL.createObjectURL(blobData); // blob객체를 가리키는 URL 생성
const link = document.createElement("a");
link.href = blobUrl; // a태그에 url 삽입
link.setAttribute("download", "line_img"); // a태그에 다운로드 속성 추가, 파일명 지정
document.body.appendChild(link);
link.click();
} else {
throw new Error(`Request failed with status: ${response.status}`);
}
})
.catch((error) => {
console.error("There was a problem with the request:", error);
});
✅ 배운 내용
💡웹뷰 환경에서는 a태그의 다운로가 작동하지 않는다
웹에서는 a태그로 파일 다운 기능이 정상작동 하였는데, 모바일에선 작동하지 않는 이슈 발생.
찰스 프록시로 디버깅해보니 api응답은 정상이였다.
찾아본 결과, 모바일 개발시 파일 다운에 대한 권한을 설정해줘야 한다고 한다.
=> 유니티 모바일 개발자에게 window.Uniti.call 함수 요청하여
모바일쪽에 파라미터 넘겨 통신하는 방법으로 해결했다.
💡axios get요청에서 파라미터 붙이기
fetch로 구현했더라면 url에 쿼리스트링으로 파라미터를 다 붙였어야 하지만
axios get요청에 쿼리스트링을 붙일 땐 "params" 사용한다.
- fetch로 구현했더라면 이렇게 구현됐을 것임
(new URLSearchParams로 쿼리스트링 보내면 자동으로 인코딩됨)
const queryParams = new URLSearchParams({
format: "dxf",
layerName: "layer_name",
viewparams: "c_id:1;o_id:1,2,3,;r_id:40011;"
});
fetch(`/download/file?${queryParams}`, {
method: "GET",
headers: {
Accept: "application/octet-stream",
},
})
// /download/file?format=dxf&layerName=layer_name&viewparams=c_id:1;o_id:1,2,3,;r_id:40011;
💡responseType
responseType종류
: text(아무설정 없으면 default), arraybuffer, blob, document
file을 받을 떈
-blob과 arraybuffer 를 설정해 받을 수 있다
-blob(binary large object)
: 바이너리 데이터를 저장하기 위한 객체, 바이너리 형태로 큰 객체를 저장함.
: 바이너리 데이터 - 주로 이미지, 비디오, 사운드 등 멀티미디어 파일
blob와 arraybuffer 차이
: 둘다 file data를 받을 때 사용
: arraybuffer는 - js에서 조작하기 쉬운 "배열" 형태로 data를 받을 수 있다.
파일을 응답받을 땐, response type을 설정해야 하는 이유
- dxf파일과, zip파일을 응답받아 다운받아야 했었는데, 처음엔 response type을 설정하지 않아 그냥 텍스트로 응답이 왔다.
때문에 파일이 다운되지 않는 결과 발생.
- 해결 : dxf 파일은 blob로, zip파일은 파일이 여러개 있기 떄문에 arraybuffer 형태로 응답받도록 구현하였다.
dxf파일은 이진 데이터 형식이기 때문에 다운받은 파일이 깨질 것 이다.
따라서 다운할 파일이 "이진 데이터" 형식인 경우, 이진 데이터를 유지하기 위해 responseType을 설정한다.
💡 window.URL.createObjectURL()
특정 파일이나,blob를 객체 url로 만들때 사용.
파라미터에 blob객체를 넣어 호출하면, 해당 파일 전체 내용을 url 텍스트로 변환한 값이 나온다.
💡a태그의 download 속성
사용자가 링크를 클릭하면 해당 대상 주소로 연결되지 않고, 대신 해당 콘텐츠가 다운됨.
다운로드되는 파일의 원래 이름이 사용되지만, 직접 다운받은 파일의 이름을 지정해 줄 수도 있다.
ex)
<a href="photo.png" download>다운로드</a>
<a href="photo.png" download="이름지정">다운로드</a>
https://jw910911.tistory.com/119
XMLHttpRequest: responseType property
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType
https://sybarits.github.io/2020/05/26/response-type.html
URL. createObjectURL
https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL_static
https://kyounghwan01.github.io/blog/JS/JSbasic/Blob-url/#createobjecturl
'프론트엔드' 카테고리의 다른 글
pwa 웹앱 설치하기 - manifest.json (0) | 2023.11.26 |
---|---|
네이티브 앱, 웹앱, 웹뷰(하이브리드앱) (0) | 2023.11.19 |
강제로 리렌더링 시키기 (0) | 2023.10.29 |
Chrome Network 패널 (0) | 2023.07.03 |
[SQL] 프로그래머스 - 그룹별 조건에 맞는 식당 목록 출력하기 (0) | 2023.05.26 |
✅ 문제-해결
문제1. api get요청시 쿼리스트링 문자로 호출하면 에러나는 문제
처음엔 일단 통신이 잘 되는지만 확인해보려고 axios url에 파라미터를 쿼리스트링으로 직접 작성해줬다.
그런데 400 에러가 발생하였고, 이것 때문에 파라미터 값에 문제가 있는 줄 알아 애먹었다.
그러다 axios의 params로 파라미터를 담아줬더니 정상적으로 응답이 되었다.
결국 두 url 다 동일한 주소일텐데 왜 다른걸까 의문이다.
→ 두 url이 실제 api를 요청할 때 인코딩여부가 다른데 이게 영향이 있는 것 같다.
- params : 인코딩을 해준다. (axios 라이브러리에서 해주는듯)
- 쿼리스트링 : 인코딩 안해줌, 인코딩을 안하면 문제가 되는 문자열이 있어서 오류난 것 같음
(url주소에 backslash"\"가 여러 있었는데, 백슬래시는 url에 잘 안쓰는 것으로 알고있음)
→ fetch로 get요청시 쿼리스트링을 보낸다면, URLSearchParams 사용
- URLSearchParams 로 쿼리스트링 보내면 자동으로 인코딩됨
문제2. 브라우저에서 파일 다운되지 않는 문제
api통신으로 파일을 응답받았지만 그 뿐, 다운로드 파일을 사용자에게 보여지는 문제 발생.
[원인1] 응답 데이터는 문자열이였다.
→ responseType을 blob으로 붙여 dxf파일 형식의 응답을 받아야 했었다.
응답 결과 : Blob {size: 11111, type: 'application/octet-stream'}
(단순 객체처럼 보이지만 Blob는 생성자 함수고 인스턴스 객체인 것임)
→ 응답 데이터를 zip파일로 받을 땐 responseType을 arraybuffer 로 처리했음
[원인2] a태그를 이용하여 chrome에서 다운로드 팝업창 띄우도록 처리하여 해결
✅ 구현코드
axios({
url: "/download/file",
method: "GET",
params: {
format: "dxf",
layerName: "layer_name",
viewparams: `c_id:1;o_id:1,2,3,;r_id:40011;`
},
responseType: "blob" // 응답 타입을 blob로 지정
})
.then((response) => {
if (response.status === 200) {
const blobData = response.data; // 응답 데이터는 blob 이다.// Blob {size: 1818717, type: 'application/octet-stream'}
const blobUrl = URL.createObjectURL(blobData); // blob객체를 가리키는 URL 생성
const link = document.createElement("a");
link.href = blobUrl; // a태그에 url 삽입
link.setAttribute("download", "line_img"); // a태그에 다운로드 속성 추가, 파일명 지정
document.body.appendChild(link);
link.click();
} else {
throw new Error(`Request failed with status: ${response.status}`);
}
})
.catch((error) => {
console.error("There was a problem with the request:", error);
});
✅ 배운 내용
💡웹뷰 환경에서는 a태그의 다운로가 작동하지 않는다
웹에서는 a태그로 파일 다운 기능이 정상작동 하였는데, 모바일에선 작동하지 않는 이슈 발생.
찰스 프록시로 디버깅해보니 api응답은 정상이였다.
찾아본 결과, 모바일 개발시 파일 다운에 대한 권한을 설정해줘야 한다고 한다.
=> 유니티 모바일 개발자에게 window.Uniti.call 함수 요청하여
모바일쪽에 파라미터 넘겨 통신하는 방법으로 해결했다.
💡axios get요청에서 파라미터 붙이기
fetch로 구현했더라면 url에 쿼리스트링으로 파라미터를 다 붙였어야 하지만
axios get요청에 쿼리스트링을 붙일 땐 "params" 사용한다.
- fetch로 구현했더라면 이렇게 구현됐을 것임
(new URLSearchParams로 쿼리스트링 보내면 자동으로 인코딩됨)
const queryParams = new URLSearchParams({
format: "dxf",
layerName: "layer_name",
viewparams: "c_id:1;o_id:1,2,3,;r_id:40011;"
});
fetch(`/download/file?${queryParams}`, {
method: "GET",
headers: {
Accept: "application/octet-stream",
},
})
// /download/file?format=dxf&layerName=layer_name&viewparams=c_id:1;o_id:1,2,3,;r_id:40011;
💡responseType
responseType종류
: text(아무설정 없으면 default), arraybuffer, blob, document
file을 받을 떈
-blob과 arraybuffer 를 설정해 받을 수 있다
-blob(binary large object)
: 바이너리 데이터를 저장하기 위한 객체, 바이너리 형태로 큰 객체를 저장함.
: 바이너리 데이터 - 주로 이미지, 비디오, 사운드 등 멀티미디어 파일
blob와 arraybuffer 차이
: 둘다 file data를 받을 때 사용
: arraybuffer는 - js에서 조작하기 쉬운 "배열" 형태로 data를 받을 수 있다.
파일을 응답받을 땐, response type을 설정해야 하는 이유
- dxf파일과, zip파일을 응답받아 다운받아야 했었는데, 처음엔 response type을 설정하지 않아 그냥 텍스트로 응답이 왔다.
때문에 파일이 다운되지 않는 결과 발생.
- 해결 : dxf 파일은 blob로, zip파일은 파일이 여러개 있기 떄문에 arraybuffer 형태로 응답받도록 구현하였다.
dxf파일은 이진 데이터 형식이기 때문에 다운받은 파일이 깨질 것 이다.
따라서 다운할 파일이 "이진 데이터" 형식인 경우, 이진 데이터를 유지하기 위해 responseType을 설정한다.
💡 window.URL.createObjectURL()
특정 파일이나,blob를 객체 url로 만들때 사용.
파라미터에 blob객체를 넣어 호출하면, 해당 파일 전체 내용을 url 텍스트로 변환한 값이 나온다.
💡a태그의 download 속성
사용자가 링크를 클릭하면 해당 대상 주소로 연결되지 않고, 대신 해당 콘텐츠가 다운됨.
다운로드되는 파일의 원래 이름이 사용되지만, 직접 다운받은 파일의 이름을 지정해 줄 수도 있다.
ex)
<a href="photo.png" download>다운로드</a>
<a href="photo.png" download="이름지정">다운로드</a>
https://jw910911.tistory.com/119
XMLHttpRequest: responseType property
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseType
https://sybarits.github.io/2020/05/26/response-type.html
URL. createObjectURL
https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL_static
https://kyounghwan01.github.io/blog/JS/JSbasic/Blob-url/#createobjecturl
'프론트엔드' 카테고리의 다른 글
pwa 웹앱 설치하기 - manifest.json (0) | 2023.11.26 |
---|---|
네이티브 앱, 웹앱, 웹뷰(하이브리드앱) (0) | 2023.11.19 |
강제로 리렌더링 시키기 (0) | 2023.10.29 |
Chrome Network 패널 (0) | 2023.07.03 |
[SQL] 프로그래머스 - 그룹별 조건에 맞는 식당 목록 출력하기 (0) | 2023.05.26 |