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.com
api.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');