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 相关文章推荐
javascript div 遮罩层封锁整个页面
Jul 10 Javascript
niceTitle 基于jquery的超链接提示插件
May 31 Javascript
JavaScript var声明变量背后的原理示例解析
Oct 12 Javascript
jquery自动切换tabs选项卡的具体实现
Dec 24 Javascript
Javascript四舍五入Math.round()与Math.pow()使用介绍
Dec 27 Javascript
JavaScript数组前面插入元素的方法
Apr 06 Javascript
用canvas 实现个图片三角化(LOW POLY)效果
Feb 18 Javascript
js的各种排序算法实现(总结)
Jul 23 Javascript
Bootstrap中的Dropdown下拉菜单更改为悬停(hover)触发
Aug 31 Javascript
Javascript柯里化实现原理及作用解析
Oct 22 Javascript
vue 表单输入框不支持focus及blur事件的解决方案
Nov 17 Vue.js
react使用antd的上传组件实现文件表单一起提交功能(完整代码)
Jun 29 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
全国FM电台频率大全 - 22 重庆市
2020/03/11 无线电
深入解析PHP垃圾回收机制对内存泄露的处理
2013/06/14 PHP
使用PHPMailer实现邮件发送代码分享
2014/10/23 PHP
PHP实现bitmap位图排序与求交集的方法
2016/07/28 PHP
php is_executable判断给定文件名是否可执行实例
2016/09/26 PHP
thinkphp5.1框架实现格式化mysql时间戳为日期的方式小结
2019/10/10 PHP
js innerHTML 的一些问题的解决方法
2008/06/22 Javascript
JS弹出层的显示与隐藏示例代码
2013/12/27 Javascript
Internet Explorer 11 浏览器介绍:别叫我IE
2014/09/28 Javascript
jquery中radio checked问题
2015/03/16 Javascript
Clipboard.js 无需Flash的JavaScript复制粘贴库
2015/10/02 Javascript
为何JS操作的href都是javascript:void(0);呢
2015/11/12 Javascript
jquery获取复选框的值的简单实例
2016/05/26 Javascript
浅谈JavaScript中的分支结构
2016/07/01 Javascript
JavaScript原型继承_动力节点Java学院整理
2017/06/30 Javascript
js实现1,2,3,5数字按照概率生成
2017/09/12 Javascript
vue地址栏直接输入路由无效问题的解决
2018/11/15 Javascript
js new Date()实例测试
2019/10/31 Javascript
python 将字符串转换成字典dict
2013/03/24 Python
Python实现Sqlite将字段当做索引进行查询的方法
2016/07/21 Python
Python文件循环写入行时防止覆盖的解决方法
2018/11/09 Python
Pycharm远程连接服务器并实现代码同步上传更新功能
2020/02/25 Python
Python pandas 列转行操作详解(类似hive中explode方法)
2020/05/18 Python
对Keras中predict()方法和predict_classes()方法的区别说明
2020/06/09 Python
Python离线安装各种库及pip的方法
2020/11/28 Python
世界上最大的售后摩托车零配件超市:J&P Cycles
2017/12/08 全球购物
意大利网上药房:Farmacia 33
2020/01/27 全球购物
致标枪运动员广播稿
2014/02/06 职场文书
八项规定整改方案
2014/02/21 职场文书
我们的节日清明节活动总结
2014/04/30 职场文书
最新优秀教师个人先进事迹材料
2014/05/06 职场文书
科技工作者先进事迹
2014/08/16 职场文书
自动化专业大学生职业生涯规划范文:爱拚才会赢
2014/09/12 职场文书
离婚承诺书格式范文
2015/05/04 职场文书
走进科学观后感
2015/06/18 职场文书
2016党校培训心得体会
2016/01/07 职场文书