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


Posted in Javascript onJanuary 06, 2017

前言

最近因为工作需要,需要把爱词霸的每日一句引入到页面上,爱词霸向外开放了 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),即只允许与同域下的接口交互。

同域是指:

  1. 同协议:如都是 http 或者 https
  2. 同域名:如都是 http://konghy.cn/a 或 http://konghy.cn/b
  3. 同端口:如都是 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)
 }
})

如果你使用的是 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>

总结

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

参考资料

https://3water.com/article/75669.htm

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

Javascript 相关文章推荐
不用锚点也可以平滑滚动到页面的指定位置实现代码
May 08 Javascript
jquery实现浮动的侧栏实例
Jun 25 Javascript
【JS+CSS3】实现带预览图幻灯片效果的示例代码
Mar 17 Javascript
vuejs在解析时出现闪烁的原因及防止闪烁的方法
Sep 19 Javascript
原生JS查找元素的方法(推荐)
Nov 22 Javascript
EasyUI折叠表格层次显示detailview详解及实例
Dec 28 Javascript
Javascript DOM事件操作小结(监听鼠标点击、释放,悬停、离开等)
Jan 20 Javascript
Node.js利用console输出日志文件的方法示例
Apr 27 Javascript
解决vue cli使用typescript后打包巨慢的问题
Sep 30 Javascript
jQuery+PHP+Ajax实现动态数字统计展示功能
Dec 25 jQuery
js 获取本周、上周、本月、上月、本季度、上季度的开始结束日期
Feb 01 Javascript
理解Proxy及使用Proxy实现vue数据双向绑定操作
Jul 18 Javascript
js实现前端分页页码管理
Jan 06 #Javascript
纯js实现倒计时功能
Jan 06 #Javascript
JS正则截取两个字符串之间及字符串前后内容的方法
Jan 06 #Javascript
微信小程序开发教程-手势解锁实例
Jan 06 #Javascript
jQuery ajax的功能实现方法详解
Jan 06 #Javascript
详解JS中定时器setInterval和setTImeout的this指向问题
Jan 06 #Javascript
Jqprint实现页面打印
Jan 06 #Javascript
You might like
树型结构列出指定目录里所有文件的PHP类
2006/10/09 PHP
ThinkPHP函数详解之M方法和R方法
2015/09/10 PHP
CodeIgniter配置之config.php用法实例分析
2016/01/19 PHP
Twig模板引擎用法入门教程
2016/01/20 PHP
PHP反射API示例分享
2016/10/08 PHP
PHP消息队列实现及应用详解【队列处理订单系统和配送系统】
2019/05/20 PHP
php实现根据身份证获取精准年龄
2020/02/26 PHP
Swoole源码中如何查询Websocket的连接问题详解
2020/08/30 PHP
javaScript对象和属性的创建方法
2007/01/15 Javascript
DOM节点删除函数removeChild()用法实例
2015/01/12 Javascript
使用ionic切换页面卡顿的解决方法
2016/12/16 Javascript
使用JS实现图片轮播的实例(前后首尾相接)
2017/09/21 Javascript
关于vue-router的那些事儿
2018/05/23 Javascript
vue router总结 $router和$route及router与 router与route区别
2019/07/05 Javascript
Javascript地址引用代码实例解析
2020/02/25 Javascript
jQuery实现移动端下拉展现新的内容回弹动画
2020/06/24 jQuery
python模拟登陆阿里妈妈生成商品推广链接
2014/04/03 Python
windows下python安装paramiko模块和pycrypto模块(简单三步)
2017/07/06 Python
Python标准库笔记struct模块的使用
2018/02/22 Python
对Python发送带header的http请求方法详解
2019/01/02 Python
python tkinter之 复选、文本、下拉的实现
2020/03/04 Python
python编写俄罗斯方块
2020/03/13 Python
keras 读取多标签图像数据方式
2020/06/12 Python
Python 爬虫的原理
2020/07/30 Python
浅谈Python xlwings 读取Excel文件的正确姿势
2021/02/26 Python
Pretty Little Thing爱尔兰:时尚女性服饰
2017/03/27 全球购物
Bonami斯洛伐克:购买家具和家居饰品
2019/07/02 全球购物
英国豪华家具和经典家居饰品购物网站:OKA
2020/06/05 全球购物
SQL Server的固定数据库角色都有哪些?对应的服务器权限有哪些?
2013/05/18 面试题
员工试用期考核自我鉴定
2014/04/13 职场文书
踏青活动策划方案
2014/08/19 职场文书
禁毒宣传活动总结
2014/08/26 职场文书
财务整改报告范文
2014/11/05 职场文书
2017年寒假少先队活动总结
2016/04/06 职场文书
创新创业项目计划书该怎样写?
2019/08/13 职场文书
创业计划书之熟食店
2019/10/16 职场文书