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 相关文章推荐
HTML 自动伸缩的表格Table js实现
Apr 01 Javascript
修改好的jquery滚动字幕效果实现代码
Jun 22 Javascript
扩展Jquery插件处理mouseover时内部有子元素时发生样式闪烁
Dec 08 Javascript
深入理解JavaScript是如何实现继承的
Dec 12 Javascript
jQuery打印图片pdf、txt示例代码
Jul 22 Javascript
JavaScript中getUTCSeconds()方法的使用详解
Jun 11 Javascript
jqueryMobile 动态添加元素,展示刷新视图的实现方法
May 28 Javascript
jQuery.form.js插件不能解决连接超时(timeout)的原因分析及解决方法
Oct 14 Javascript
jQuery EasyUI Panel面板组件使用详解
Feb 28 Javascript
Node.js使用gm拼装sprite图片
Jul 04 Javascript
vue生成token保存在客户端localStorage中的方法
Oct 25 Javascript
微信小程序wx.request实现后台数据交互功能分析
Nov 25 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
PHP代码网站如何防范SQL注入漏洞攻击建议分享
2012/03/01 PHP
php查询相似度最高的字符串的方法
2015/03/12 PHP
php中Snoopy类用法实例
2015/06/19 PHP
PhpStorm配置Xdebug调试的方法步骤
2019/02/02 PHP
PHP实现简单的计算器
2020/08/28 PHP
摘自启点的main.js
2008/04/20 Javascript
js中cookie的使用详细分析
2008/05/28 Javascript
jQuery 1.5.1 发布,全面支持IE9 修复大量bug
2011/02/26 Javascript
兼容IE和Firefox的javascript获取iframe文档内容的函数
2011/08/15 Javascript
javascript学习笔记(四) Number 数字类型
2012/06/19 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(三)情景对话中仿打字机输出文字
2013/01/23 Javascript
asp.net刷新本页面的六种方法总结
2014/01/07 Javascript
提高NodeJS中SSL服务的性能
2014/07/15 NodeJs
bootstrap中的 form表单属性role=&quot;form&quot;的作用详解
2017/01/20 Javascript
vue实现百度搜索下拉提示功能实例
2017/06/14 Javascript
ES6新增数据结构WeakSet的用法详解
2017/08/07 Javascript
js嵌套的数组扁平化:将多维数组变成一维数组以及push()与concat()区别的讲解
2019/01/19 Javascript
layer.js open 隐藏滚动条的例子
2019/09/05 Javascript
nodejs的安装使用与npm的介绍
2019/09/11 NodeJs
浅谈es6中的元编程
2020/12/01 Javascript
python实现将汉字转换成汉语拼音的库
2015/05/05 Python
简单谈谈Python中的json与pickle
2017/07/19 Python
python添加模块搜索路径方法
2017/09/11 Python
基于python socketserver框架全面解析
2017/09/21 Python
django中forms组件的使用与注意
2019/07/08 Python
Melijoe英国官网:法国儿童时尚网站
2016/11/18 全球购物
司机的工作范围及职责
2013/11/13 职场文书
最新创业融资计划书
2014/01/19 职场文书
学生会离职感言
2014/02/11 职场文书
2014年国培研修感言
2014/03/09 职场文书
医药公司采购员岗位职责
2014/09/12 职场文书
清洁工个人总结
2015/03/04 职场文书
导游词之无锡古运河
2019/11/14 职场文书
web前端之css水平居中代码解析
2021/05/20 HTML / CSS
德劲DE1107指针试高灵敏度全波段收音机机评
2022/04/05 无线电