JavaScript用JSONP跨域请求数据实例详解

网络编程 2021-07-04 19:20www.168986.cn编程入门
Javascript跨域访问是web开发者经常遇到的问题,什么是跨域,就是一个域上加载的脚本获取或操作另一个域上的文档属性。狼蚁网站SEO优化这篇文章主要介绍了JavaScript用JSONP跨域请求数据的方法,需要的朋友可以参考借鉴,狼蚁网站SEO优化来一起看看吧。

前言

最近因为工作需要,需要把爱词霸的每日一句引入到页面上,爱词霸向外开放了 接口返回 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('Aess-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./dsapi/", showIcibaDS);
</script>

运行之后数据并没有获取到,而是出现了如下错误提示

XMLHttpRequest cannot load http://open.iciba./dsapi/. Response to preflight request doesn't pass aess control check: No 'Aess-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed aess. The response had HTTP status code 501.

这就是跨域请求的问题。那么什么是跨域请求呢?浏览器出于安全方面的考虑,采用同源策略(Same origin Policy),即只允许与同域下的接口交互。

同域是指

  1. 同协议如都是 http 或者 https
  2. 同域名如都是 http://konghy./a 或 http://konghy./b
  3. 同端口如都是 80 端口

也就是说,用户打开了页面: http://blog.konghy., 当前页面下的 js 向 http://blog.konghy./XXX 的接口发数据请求,浏览器是允许的。但假如向: http://open.iciba./xxx 发数据请求则会被浏览器阻止掉,因为存在跨域调用。

跨域请求的解决办法就是 . 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./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./aj/index',
 key: 'jsoncallback',
 data: { page: 1, cate: 'remend' },
 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./dsapi/",
 data: "",
 timeout: 3000,
 contentType: "application/json;utf-8",
 suess: function(data) {
 console.log(data);
 }
 });
})
</script>

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

参考资料


https://zhuanlan.zhihu./p/22600501

Copyright © 2016-2025 www.168986.cn 狼蚁网络 版权所有 Power by