JSONP

동일 출처 정책을 우회하는 데 사용되는 레거시 데이터 가져오기 기술에 대한 간략한 소개

  • #javascript
  • #json
  • #cors
  • #legacy

JSONP는 JSON with Padding이라고도 알려져 있으며 CORS(Cross-Origin Resource Sharing) 정책에 의해 가로채지 않고 데이터를 요청하는 기술입니다. 기본적으로 이 방법을 사용하면 브라우저에서 시행하는 CORS 검사를 우회할 수 있습니다. 내 경험에 따르면 많은 중국 웹사이트에서는 여전히 이 기술을 사용하여 데이터를 가져옵니다.

부인 성명

한국어 실력이 부적하여 이 글이 구글 번역기를 주로 활용했기 때문에 부정확한 문법과 어휘가 있을수 있습니다. 이 점 양해 부탁드리며, 추후에 다시 검토하여 수정하도록 하겠습니다.

시나리오

웹 애플리케이션이 www.a.com에 호스팅되어 있고 JavaScript 코드 중 하나가 www.b.com에 호스팅된 원격 서버에서 데이터를 가져오려고 한다고 가정해 보겠습니다. 원격 서버가 * 또는 www.a.com으로 설정된 Access-Control-Allow-Origin 헤더를 사용하여 쿼리에 응답하지 않으면 브라우저는 응답을 수신하고 해석할 때 오류를 발생시키고 거부합니다. 요청한 데이터.

해법

옵션 1: CORS 구성

문제를 해결하는 가장 안전하고 일반적인 방법은 'Access-Control-Allow-Origin' 헤더가 적절한 도메인을 가리키도록 설정하여 백엔드 서버에서 CORS를 올바르게 구성하는 것입니다. 리소스가 Azure, GCP 또는 AWS와 같은 클라우드에서 호스팅되는 경우 CORS를 활성화하는 설정도 있을 것입니다.

옵션 2: JSONP 사용

JSONP에는 수신된 응답을 활용하기 위해 따라야 하는 특정 규칙 세트가 있습니다.

포맷

다음은 https://a.com/sample.json에 원시 JSON 형식의 예제 데이터입니다.

{
  "name": "Jane",
  "age": 14,
  "school": "Stanford High School"
}

다음은 URL https://a.com/sample?callback=callback에 있는 JSONP 형식의 데이터입니다.

callback({
  name: 'Jane',
  age: 14,
  school: 'Stanford High School',
})

본질적으로 이는 요청된 데이터에 대한 JavaScript 함수 호출일 뿐이며 함수 이름은 '콜백' 쿼리 매개변수로 수정될 수 있습니다. 콜백 함수는 우리가 "패딩(Padding)"이라고 부르는 것입니다. 예를 들어 https://a.com/sample?callback=cb를 호출하면 반환된 데이터는 cb 함수로 묶입니다.

cb({
  name: 'Jane',
  age: 14,
  school: 'Stanford High School',
})

주목해야 할 한 가지 중요한 주의 사항은 제공된 콜백 함수 이름이 무엇이든 제공된 데이터를 의미 있게 사용하려면 함수가 존재해야 한다는 것입니다. 그렇지 않으면 오류가 발생합니다.

Uncaught ReferenceError: <method> is not defined

용법

요청된 데이터를 사용하려면 쿼리 매개변수에 제공된 동일한 이름으로 JavaScript 콜백 함수를 정의하고 JSONP 데이터가 로드되기 전에 함수가 정의되었는지 확인하세요.

function callback(data) {
  // 데이터를 처리
  console.log(data)
}

HTML로 쇼케이스

HTML에서는 다음과 같이 표시됩니다.

<!DOCTYPE html>
<html>
  <head>
    <title>JSONP Showcase</title>
  </head>
  <body>
    <script type="text/javascript">
      function myFunction(data) {
        console.log(data)
      }
    </script>

    <!-- 일반 JavaScript처럼 스크립트 태그를 사용하여 JSONP 데이터 가져오기 -->
    <script
      type="text/javascript"
      src="https://a.com/mydata?callback=myFunction"
    ></script>
  </body>
</html>

캐시 해제

JSONP 호출은 <script src="https://constant-static-url">이 상수인 경우 최적화를 위해 브라우저에 의해 캐싱됩니다. 브라우저가 오래된 데이터를 캐싱하는 것을 방지하려면 Math.random을 사용하여 콜백 함수 이름을 동적으로 생성해야 합니다.

window.onload = function () {
  var randomNum = Math.floor(100_000 * Math.random())
  var functionName = 'cb_' + randomNum

  window[functionName] = function (data) {
    console.log(data)
  }

  // 스크립트 태그를 동적으로 생성해야 합니다.
  var newScriptTag = document.createElement('script')
  newScriptTag.src = 'https://a.com/mydata?callback=' + functionName

  document.body.appendChild(newScriptTag)
}

이 접근 방식을 사용하면 브라우저는 대부분의 경우 최신 데이터를 요청합니다.

청소

브라우저에서 이미 데이터를 사용하고 있으므로 동적으로 생성된 스크립트 태그를 선택적으로 제거할 수 있습니다.

window.onload = function () {
  var randomNum = Math.floor(100_000 * Math.random())
  var functionName = 'cb_' + randomNum

  window[functionName] = function (data) {
    console.log(data)
  }

  // 스크립트 태그를 동적으로 생성해야 합니다.
  var newScriptTag = document.createElement('script')
  newScriptTag.id = 'script_' + functionName
  newScriptTag.src = 'https://a.com/mydata?callback=' + functionName

  document.body.appendChild(newScriptTag)
  document.getElementById(newScriptTag.id).remove()
}

정리를 통해 JSONP 호출이 원활하게 표시됩니다.

장점과 단점

장점

  • 크로스 도메인 요청: CORS 정책에 의해 시행되는 경계를 벗어날 수 있습니다.
  • 사용하기 쉬움: 복잡한 설정 코드 없이 HTML에서 <script> 태그를 사용하기만 하면 됩니다.
  • 뛰어난 브라우저 호환성: 단순한 JavaScript 함수 호출이기 때문에 모든 브라우저에서 지원합니다.

단점

  • 보안위험 : 취약한 특성으로 인해 악성코드에 의해 악용될 수 있습니다.
  • 오류 처리 없음: 오류가 발생한 경우. 함수가 정의되지 않았거나 서버가 응답하지 않는 경우 해당 오류를 콘솔에 표시하는 것 외에는 오류를 처리할 수 있는 방법이 없습니다.
  • 서버에 따라 다름: 서버가 JSONP 엔드포인트를 제공하지 않으면 JSONP를 사용할 방법이 없습니다.
  • GET 요청만 지원: JSONP 요청은 <script> 태그만 사용한다는 것을 이미 알고 있으므로 GET 이외의 다른 HTTP 메서드를 지원할 방법은 없습니다.

참고

JSONP. Wikipedia. Retrieved 2024, March 24 from https://en.wikipedia.org/wiki/JSONP
Maccana, M., Cheeso. What is JSONP, and why was it created?https://stackoverflow.com/questions/2067472/what-is-jsonp-and-why-was-it-created
Cieślar, M. JSONP demystified: What it is and why it exists. LogRocket. https://blog.logrocket.com/jsonp-demystified-what-it-is-and-why-it-exists/
Vinod. Understanding JSONP.https://www.youtube.com/watch?v=3AoeiQa8mY8