前言
最近因為工作需要,需要把愛詞霸的每日一句引入到頁面上,愛詞霸向外開放了 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.
那什麼是跨域請求呢?瀏覽器出於安全性的考慮,採用同源策略(Same origin Policy),即只允許與同域下的介面互動。
同域是指:
同協定:如都是http 或https
同網域是指:
同協定:如都是http 或https
同網域:如都是http://konghy.cn/a 或http://konghy.cn/b
同埠:如都是80 埠
也就是說,使用者開啟了頁面: http://blog.konghy.cn, 目前頁面下的js 向http://blog.konghy.cn/XXX 的介發資料請求,瀏覽器是允許的。但假如向: http://open.iciba.com/xxx 發送資料請求會被瀏覽器阻止掉,因為有跨網域呼叫。
跨域請求的解決方法是 JSONP(JSON with Padding) . HTML 中script 標籤可以載入其他網域下的js, JSONP 就是透過script 標籤載入資料的方式去取得資料當做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) } })🎜🎜🎜 🎜 🎜🎜總結🎜🎜以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或工作能帶來一定的幫助,如果有疑問大家可以留言交流。 🎜🎜更多JavaScript用JSONP跨域請求資料實例詳解相關文章請關注PHP中文網! 🎜🎜🎜🎜