머리말
최근 업무상 iCiba의 일상 문장을 페이지에 소개해야 합니다. iCiba는 API를 외부에 공개했고, 인터페이스는 json 데이터를 반환합니다. 페이지가 가벼워서 jQuery를 사용하지 않고 순수 js로 직접 코드 조각을 작성했습니다.
<script type="text/javascript"> function httpGetAsync(theUrl, callback) { xmlHttp = null; if (window.XMLHttpRequest) {// code for IE7, Firefox, Opera, etc. xmlHttp = new XMLHttpRequest(); } else if (window.ActiveXObject) {// code for IE6, IE5 xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } if (xmlHttp != null) { xmlHttp.onreadystatechange = function() { if (xmlHttp.readyState == 4 && xmlHttp.status == 200) { callback(xmlHttp.responseText); } else { console.error("Problem retrieving XML data"); } } xmlHttp.open("GET", theUrl, true); // true for asynchronous xmlHttp.setRequestHeader('Access-Control-Allow-Origin', '*'); xmlHttp.send(null); } else { console.error("Your browser does not support XMLHTTP."); } } function showIcibaDS(ds_data) { // show daily sentence content = ds_data.content; note = ds_data.note; document.write(content + '<br>'); document.write(note); } httpGetAsync("http://open.iciba.com/dsapi/", showIcibaDS); </script>
실행 후 데이터를 얻지 못했습니다. 그런데 다음과 같은 오류 메시지가 나타났습니다.
XMLHttpRequest cannot load http://open.iciba.com/dsapi/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 501.
이것은 도메인 간 요청 문제입니다. 그렇다면 교차 도메인 요청이란 무엇입니까? 보안상의 이유로 브라우저는 동일한 도메인의 인터페이스와의 상호 작용만 허용하는 동일 출처 정책을 채택합니다.
동일한 도메인은 다음을 의미합니다.
동일한 프로토콜: http 또는 https 등
동일한 도메인 이름: http://konghy.cn/a 또는 http: / /konghy.cn/b
동일 포트: 둘 다 80포트인 경우
즉, 사용자가 현재 페이지 아래 http://blog.konghy.cn 페이지를 열었습니다. Node.js는 브라우저에서 허용하는 http://blog.konghy.cn/XXX 인터페이스에 데이터 요청을 보냅니다. 그러나 http://open.iciba.com/xxx로 데이터 요청을 보내면 도메인 간 호출이 있기 때문에 브라우저에 의해 차단됩니다.
교차 도메인 요청에 대한 솔루션은 JSONP(JSON with Padding)입니다. HTML의 스크립트 태그는 다른 도메인의 js를 로드할 수 있습니다. JSONP는 스크립트 태그를 사용하여 데이터를 가져와서 JS로 실행합니다. 그런 다음 콜백 함수를 사용하여 데이터를 추출합니다.
<script type="text/javascript"> var cur_date = new Date(); document.getElementById("cur_year").innerHTML = cur_date.getFullYear(); function showIcibaDS(ds_data) { // show daily sentence content = ds_data.content; note = ds_data.note; ds_p = document.getElementById("iciba_ds") var content_span = document.createElement('span'); var note_span = document.createElement('span'); var br = document.createElement('br') content_span.innerHTML = content note_span.innerHTML = note ds_p.appendChild(content_span); ds_p.appendChild(br); ds_p.appendChild(note_span); } </script> <script type="text/javascript" src="http://open.iciba.com/dsapi/?callback=showIcibaDS"></script>
그런 다음 정보를 확인하고 누군가 이를 캡슐화했는지 확인합니다.
function jsonp(setting) { setting.data = setting.data || {} setting.key = setting.key||'callback' setting.callback = setting.callback||function(){} setting.data[setting.key] = '__onGetData__' window.__onGetData__ = function(data) { setting.callback (data); } var script = document.createElement('script') var query = [] for(var key in setting.data) { query.push(key + '=' + encodeURIComponent(setting.data[key])) } script.src = setting.url + '?' + query.join('&') document.head.appendChild(script) document.head.removeChild(script) } jsonp({ url: 'http://photo.sina.cn/aj/index', key: 'jsoncallback', data: { page: 1, cate: 'recommend' }, callback: function(ret) { console.log(ret) } })
jQuery를 사용하는 경우 Ajax를 직접 사용하여 데이터를 요청할 수 있습니다.
<script src="js/jquery-1.11.3.js"></script> <script> $(function(){ $.ajax({ async: true, type: "GET", dataType: 'jsonp', jsonp: 'callback', jsonpCallback: 'callbackfunction', url: "http://open.iciba.com/dsapi/", data: "", timeout: 3000, contentType: "application/json;utf-8", success: function(data) { console.log(data); } }); }) </script>
요약
이상은 이 글의 전체 내용입니다. 모든 분들의 공부나 업무에 조금이나마 도움이 되었으면 좋겠습니다. 궁금한 점이 있으시면 메시지를 남겨주세요.
JSONP를 사용하여 도메인 간 데이터를 요청하는 JavaScript의 자세한 예를 보려면 PHP 중국어 웹사이트에서 관련 기사를 주목하세요!