[javascript] JQuery없이 Javascript에서 JSONP 요청을 만드는 방법은 무엇입니까?

jQuery 또는 기타 외부 라이브러리를 사용하지 않고 JavaScript에서 교차 도메인 JSONP 요청을 할 수 있습니까? JavaScript 자체를 사용하고 데이터를 구문 분석하여 사용할 수 있도록 객체로 만들고 싶습니다. 외부 라이브러리를 사용해야합니까? 그렇지 않다면 어떻게해야합니까?



답변

function foo(data)
{
    // do stuff with JSON
}

var script = document.createElement('script');
script.src = '//example.com/path/to/jsonp?callback=foo'

document.getElementsByTagName('head')[0].appendChild(script);
// or document.head.appendChild(script) in modern browsers


답변

간단한 예제 (onSuccess 및 onTimeout 지원 포함). 필요한 경우 URL 내에서 콜백 이름을 전달해야합니다.

var $jsonp = (function(){
  var that = {};

  that.send = function(src, options) {
    var callback_name = options.callbackName || 'callback',
      on_success = options.onSuccess || function(){},
      on_timeout = options.onTimeout || function(){},
      timeout = options.timeout || 10; // sec

    var timeout_trigger = window.setTimeout(function(){
      window[callback_name] = function(){};
      on_timeout();
    }, timeout * 1000);

    window[callback_name] = function(data){
      window.clearTimeout(timeout_trigger);
      on_success(data);
    }

    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.src = src;

    document.getElementsByTagName('head')[0].appendChild(script);
  }

  return that;
})();

샘플 사용법 :

$jsonp.send('some_url?callback=handleStuff', {
    callbackName: 'handleStuff',
    onSuccess: function(json){
        console.log('success!', json);
    },
    onTimeout: function(){
        console.log('timeout!');
    },
    timeout: 5
});

GitHub : https://github.com/sobstel/jsonp.js/blob/master/jsonp.js


답변

JSONP 란 무엇입니까?

jsonp에서 기억해야 할 중요한 점은 실제로 프로토콜이나 데이터 유형이 아니라는 것입니다. 즉석 에서 스크립트 를 로드 하고 페이지에 도입 된 스크립트를 처리 하는 방법입니다 . JSONP의 정신에서 이것은 서버에서 클라이언트 애플리케이션 / 스크립트로 새로운 javascript 객체를 도입하는 것을 의미합니다.

JSONP는 언제 필요합니까?

하나의 도메인이 같은 페이지에있는 다른 도메인의 데이터를 비동기 적으로 액세스 / 처리하도록 허용하는 한 가지 방법입니다. 주로 XHR (ajax) 요청에서 발생하는 CORS (Cross Origin Resource Sharing) 제한을 재정의하는 데 사용됩니다. 스크립트로드에는 CORS 제한이 적용되지 않습니다.

어떻게하나요

서버에서 새로운 자바 스크립트 객체를 도입하는 것은 여러 가지 방법으로 구현할 수 있지만 가장 일반적인 방법은 서버가 필요한 객체를 전달하여 ‘콜백’함수의 실행을 구현하는 것입니다. 콜백 기능을 사용하면 클라이언트에 이미 설정 한 단지 기능입니다 스크립트가 이 시점에서 호출로드 스크립트 로드가에 전달 된 데이터를 처리 할 수 있습니다.

예:

누군가의 집에있는 모든 항목을 기록하는 응용 프로그램이 있습니다. 내 응용 프로그램이 설정되었으며 이제 주 침실에있는 모든 항목을 검색하려고합니다.

내 응용 프로그램은에 app.home.com있습니다. 데이터를로드하는 데 필요한 API가 켜져 api.home.com있습니다.

서버가이를 허용하도록 명시 적으로 설정되어 있지 않으면 별도의 하위 도메인에있는 페이지에도 XHR CORS 제한이 적용되므로이 데이터를로드하는 데 ajax를 사용할 수 없습니다.

이상적으로는 x-domain XHR을 허용하도록 설정하십시오.

이상적으로는 API와 앱이 동일한 도메인에 있으므로 .NET에서 헤더를 설정할 수있는 액세스 권한이있을 수 있습니다 api.home.com. 그렇게하면에 Access-Control-Allow-Origin: 대한 액세스 권한을 부여 하는 헤더 항목을 추가 할 수 있습니다 app.home.com. 헤더가 다음과 같이 설정되었다고 가정하면 Access-Control-Allow-Origin: "http://app.home.com"JSONP를 설정하는 것보다 훨씬 안전합니다. CORS가 전체 인터넷에 액세스 하지 않고도 app.home.com원하는 모든 것을 얻을 수 있기 때문 입니다.api.home.comapi.home.com

위의 XHR 솔루션은 불가능합니다. 클라이언트 스크립트에서 JSONP 설정 : JSONP 호출을 할 때 서버의 응답을 처리하는 함수를 설정했습니다 . :

function processJSONPResponse(data) {
    var dataFromServer = data;
}

서버는 다음과 같은 미니 스크립트를 반환하도록 설정 "processJSONPResponse('{"room":"main bedroom","items":["bed","chest of drawers"]}');"되어야 //api.home.com?getdata=room&room=main_bedroom합니다. 유사한 것이 호출 되면 그러한 문자열을 반환하도록 설계되었을 수 있습니다 .

그런 다음 클라이언트는 다음과 같이 스크립트 태그를 설정합니다.

var script = document.createElement('script');
script.src = '//api.home.com?getdata=room&room=main_bedroom';

document.querySelector('head').appendChild(script);

이것은 스크립트를로드 window.processJSONPResponse()하고 서버에 의해 쓰여진 / 에코 / 인쇄 된대로 즉시 호출 합니다. 함수에 매개 변수로 전달 된 데이터는 이제 dataFromServer로컬 변수에 저장되며 필요한 모든 작업을 수행 할 수 있습니다.

정리

클라이언트가 데이터를 가지면, 즉. 스크립트가 DOM에 추가 된 직후 DOM에서 스크립트 요소를 제거 할 수 있습니다.

script.parentNode.removeChild(script);


답변

내 이해는 실제로 JSONP와 함께 스크립트 태그를 사용한다는 것입니다.

첫 번째 단계는 JSON을 처리 할 함수를 만드는 것입니다.

function hooray(json) {
    // dealin wit teh jsonz
}

이 기능이 글로벌 수준에서 액세스 가능한지 확인하십시오.

다음으로, 스크립트 요소를 DOM에 추가합니다.

var script = document.createElement('script');
script.src = 'http://domain.com/?function=hooray';
document.body.appendChild(script);

스크립트는 API 공급자가 빌드 한 JavaScript를로드하고 실행합니다.


답변

아래와 같이 jsonp를 사용하는 방법 :

function jsonp(uri) {
    return new Promise(function(resolve, reject) {
        var id = '_' + Math.round(10000 * Math.random());
        var callbackName = 'jsonp_callback_' + id;
        window[callbackName] = function(data) {
            delete window[callbackName];
            var ele = document.getElementById(id);
            ele.parentNode.removeChild(ele);
            resolve(data);
        }

        var src = uri + '&callback=' + callbackName;
        var script = document.createElement('script');
        script.src = src;
        script.id = id;
        script.addEventListener('error', reject);
        (document.getElementsByTagName('head')[0] || document.body || document.documentElement).appendChild(script)
    });
}

그런 다음 다음과 같이 ‘jsonp’메소드를 사용하십시오.

jsonp('http://xxx/cors').then(function(data){
    console.log(data);
});

참고:

JsonP를 사용한 JavaScript XMLHttpRequest

http://www.w3ctech.com/topic/721(Promise 사용 방법에 대해 이야기)


답변

https://github.com/robertodecurnex/J50Npi/blob/master/J50Npi.js 를 수행하는 순수한 자바 스크립트 라이브러리가 있습니다.

그것을 살펴보고 코드를 사용하거나 이해하는 데 도움이 필요하면 알려주십시오.

Btw, 여기에 간단한 사용 예가 있습니다. http://robertodecurnex.github.com/J50Npi/


답변

/**
 * Loads data asynchronously via JSONP.
 */
const load = (() => {
  let index = 0;
  const timeout = 5000;

  return url => new Promise((resolve, reject) => {
    const callback = '__callback' + index++;
    const timeoutID = window.setTimeout(() => {
      reject(new Error('Request timeout.'));
    }, timeout);

    window[callback] = response => {
      window.clearTimeout(timeoutID);
      resolve(response.data);
    };

    const script = document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.src = url + (url.indexOf('?') === -1 ? '?' : '&') + 'callback=' + callback;
    document.getElementsByTagName('head')[0].appendChild(script);
  });
})();

사용 샘플 :

const data = await load('http://api.github.com/orgs/kriasoft');