首頁 > web前端 > js教程 > 主體

JavaScript用JSONP跨域請求資料實例詳解

高洛峰
發布: 2017-01-09 10:46:06
原創
1353 人瀏覽過

前言

最近因為工作需要,需要把愛詞霸的每日一句引入到頁面上,愛詞霸向外開放了 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(&#39;Access-Control-Allow-Origin&#39;, &#39;*&#39;);
 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 + &#39;<br>&#39;);
 document.write(note);
 }
 
 httpGetAsync("http://open.iciba.com/dsapi/", showIcibaDS);
</script>
登入後複製

   

運作之後資料並沒有取得到,而是出現如下錯誤提示:

XMLHttpRequest cannot load http://open.iciba.com/dsapi/. Response to preflight request doesn&#39;t pass access control check: No &#39;Access-Control-Allow-Origin&#39; header is present on the requested resource. Origin &#39;null&#39; 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(&#39;span&#39;);
 var note_span = document.createElement(&#39;span&#39;);
 var br = document.createElement(&#39;br&#39;)
 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||&#39;callback&#39;
 setting.callback = setting.callback||function(){}
 setting.data[setting.key] = &#39;__onGetData__&#39;
 
 window.__onGetData__ = function(data) {
 setting.callback (data);
 }
 var script = document.createElement(&#39;script&#39;)
 var query = []
 for(var key in setting.data)
 {
 query.push(key + &#39;=&#39; + encodeURIComponent(setting.data[key]))
 }
 script.src = setting.url + &#39;?&#39; + query.join(&#39;&&#39;)
 document.head.appendChild(script)
 document.head.removeChild(script)
}
 
jsonp({
 url: &#39;http://photo.sina.cn/aj/index&#39;,
 key: &#39;jsoncallback&#39;,
 data: { page: 1, cate: &#39;recommend&#39; },
 callback: function(ret) {
 console.log(ret)
 }
})
登入後複製
   🎜🎜🎜 🎜 🎜🎜總結🎜🎜以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或工作能帶來一定的幫助,如果有疑問大家可以留言交流。 🎜🎜更多JavaScript用JSONP跨域請求資料實例詳解相關文章請關注PHP中文網! 🎜🎜🎜🎜
相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!