Jsonp
- 웹 브라우저에서 실행되는 JavaScript는 동일 출처 정책에 따라 XMLHttpRequest 등의 직접적인 HTTP 통신을 이용해 외부 출처에서 데이터를 받아오는 것이 불가능하지만, HTML script 요소는 외부 출처로부터 조회된 내용을 실행하는 것이 허용되어 있다.
- JSONP는 동일-출처 정책을 우회하는 데이터의 공유를 가능하게 한다.
- 상속 비보안 문제로 인해 JSONP는 CORS로 대체되고 있다.
쇼핑하우 fetch 요청해보기
// 쇼핑하우에 검색어에 'abc'라고 입력했을때 url
'https://suggest-bar.daum.net/suggest?limit=10&mode=json&code=utf_in_out&q=abc&id=shoppinghow_suggest'
- 요러한 데이터가 나온다
- 이제 이것을 fetch로 요청해보자!
fetch('https://suggest-bar.daum.net/suggest?limit=10&mode=json&code=utf_in_out&q=abc&id=shoppinghow_suggest')
.then(data => data.json())
.then(data => console.log(data));
- 😎 짠! 하고 에러가 나왔다
- CORS 문제라고 한다
- Jsonp 로 바꿀차례인것 같다
쇼핑하우 Jsonp 요청하기
- javascript 는 동일 출처 정책을 따르지만
- HTML script 요소는 외부 출처로부터 조회된 내용을 실행하는 것이 허용되어 있다.
- JSONP는 이러한 웹 브라우저의 특성을 이용해, JSON 데이터를 클라이언트가 지정한 콜백 함수를 호출하는 유효한 JavaScript 문법으로 감싸 클라이언트에 전송한다.
<script>
function parseResponse(data) {
console.log(data)
}
</script>
<script
src="https://suggest-bar.daum.net/suggest?
callback=parseResponse&limit=10&mode=json&code=utf_in_out&q=abc&id=shoppinghow_suggest">
</script>
- 클라이언트가 'parseResponse'라는 함수를 JSONP 요청의 콜백 함수로 지정하였다고 하면, 다음과 같은 HTML 태그가 문서에 삽입된다.
- 위의 html 코드의 결과는 이렇게 데이터가 나오는 것을 확인할 수 있다
js 코드에서는 어떻게?
function requestJsonp(word) {
const script = document.createElement('script');
script.src = https://suggest-bar.daum.net/suggest?
callback=responseJsonpData&limit=10&mode=json&code=utf_in_out&q=${word}&id=shoppinghow_suggest;
document.body.append(script);
}
function responseJsonpData(data) {
console.log(data)
}
requestJsonp('abc');
- 이런식으로 responseJsonpData를 callback의 인자로 넣어주었다
function requestJsonp(word, callback) {
const script = document.createElement('script');
script.src = https://suggest-bar.daum.net/suggest?
callback=${callback.name}&limit=10&mode=json&code=utf_in_out&q=${word}&id=shoppinghow_suggest;
document.body.append(script);
}
function responseJsonpData(data) {
console.log(data);
}
requestJsonp('abc', responseJsonpData);
- 이렇게 해도 동일하게 작동한다
- 이렇게 해서 사용하면 된다~ (~ ̄▽ ̄)~
Webpack 사용 시 문제점
- webpack으로 js소스를 번들링하여 하나의 js 파일만 사용하고 있었는데
- 위와 동일하게 했음에도 불구하고 문제가
- 요렇게 나온다
(위의 코드는 jsonp.js파일을 html에서 번들링하지 않고 따로 불러서 사용했었다) - 분명 responseJsonpData 함수를 선언해 두었는데 찾지 못한다고 한다
- Source 탭에서 디버깅을 해본결과 responseJsonpData는 존재하고 있었다!! 왜 못찾는거지??
- 그후로 삽질 ⛏⚒🛠🔨🪓🏹🗡⚔💣⌛⏳⌚⏰⏱⏲...
결과
- webpack의 변수 유효범위는 해당파일안에서만 접근 가능하다
- ▼ 이미지는 아메리카노로 입력했을때 생성된 script
- Jsonp가 동작하게 하기 위해서는 script를 새로 생성해야 하는데 새로 생성한 스크립트에서는 접근을 할 수가 없는 것이었다!! 🎊
- 그래서 함수를 전역으로 이동시켜야 한다
https://stackoverflow.com/questions/40759250/why-webpack-use-jsonp-to-get-chunk-script
window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) { }
- jsonp를 사용하는 코드는 window 전역객체를 사용하는 코드가 보이던데 이런식으로 사용해야하나보다..
내 코드 수정
function requestJsonp(word, callbackName) {
const script = document.createElement('script');
script.src = https://suggest-bar.daum.net/suggest?
callback=${callbackName}&limit=10&mode=json&code=utf_in_out&q=${word}&id=shoppinghow_suggest;
document.body.append(script);
}
window['responseJsonpData'] = function (data) {
console.log(data);
}
requestJsonp('abc', 'responseJsonpData');
- 이런식으로 해결~ 어쩔 수 없는 전역 함수인 것 같다 (~ ̄▽ ̄)~