JS、Jquery里面的jsonp

本文详细介绍了JSONP(JSON with Padding)的工作原理及其在前端开发中的应用。文章通过实例展示了如何利用jQuery和原生JavaScript实现跨域数据请求,并提供了一个简单的PHP后端示例来配合前端实现JSONP调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考个人博客:http://www.zhuzhuman.com/nav-1/type-1/article/20.html
      我们平常使用ajax从前端发起请求获取数据,一般请求的地址都是和当前网页是同源的,即不能进行跨域请求,(跨域:主域名、子域名、端口号其中有一个不同就属于跨域);
      Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。
      虽然普通ajax不能跨域,但是script标签是可以跨域引用的,即JS可以跨域使用。因此:
      jsonp实现跨域请求数据的原理:jsonp允许服务器在后台生成一段js代码(回调函数),将数据写进回调函数里,然后返回给页面,页面接收回调函数后在页面执行,可获取到数据。注:因此,jsonp返回给页面的不是数据本身,而是回调函数,数据可从回调函数中获取。

举例:

  1. jquery写法:
    第一种写法:ajax
<script type="text/javascript">
	// 前端通过jquery发起ajax请求
	$.ajax({
		type : "GET", // 获取方式,好像jsonp不支持post...
		url : "http://127.0.0.1/jsonp/jsonp.php", // 请求的地址
		async:false, // 同步
		dataType : "jsonp", // 数据类型,必须是jsonp,这样才能进行跨域操作
		data : "", // 传给后台的数据,可省略。
		jsonp : "callback", // 用于指定回调函数,可为任意名字,但是必须和后台用GET获取用的名字保持一致。
		jsonpCallback : "myCallBack", // 自定义回调函数名,可省略,默认jq会自动随机生成函数名传给后台。
		success : function (data) { // 请求成功时执行的函数,其中data就是后台数据。
			console.log(data); 
		},
		error : function (e) {
			console.log("e");
		}
	})
</script>

第二种写法: get请求

<script type="text/javascript">
	$.getJSON('http://127.0.0.1/jsonp/jsonp.php?callback=?',function (data) {
		console.log(data);
	}); // ?后面的callback=?用来标识是jsonp请求。其中callback必须和后台get获取数据时用的名字一样。
</script>

2.原生JS实现jsonp

function jsonp(options) {
	// 请求参数设置
	options = options || {};
	// 创建js标签用于执行jsonp
    var oHead = document.getElementsByTagName('head')[0];
    var oScript = document.createElement('script');
    // 给window绑定和callback参数值相同的函数,用于获数据
    var _callback = options.callback;
    window[_callback] = function (data) {
    	// 形参data 用于接收后台返回的 callback函数 的实参(数据)
    	// 获取数据成功后清除jsonp的js
    	oHead.removeChild(oScript);
    	// 清除加载超时的定时函数(加载成功,超时函数不用执行了)
    	clearTimeout(oScript.timer);
    	// 清除回调函数
    	window[_callback] = null;
    	// 执行请求成功的回调函数,把callback里的参数再传给succeed函数。succeed 函数里面执行对数据的操作
    	options.success && options.success(data);
    }
    // js发起请求,请求成功后返回的代码是让 callback 执行的,而且实参就是后台数据
    var url = options.url.indexOf('?') > -1 ? options.url + '&callback=' + options.callback : options.url + '?callback=' + options.callback;
    if(options.data) {
    	for(var k in options.data) {
    		url += '&' + k + '=' + options.data[k];
		}
    }
    oScript.src = url;
    oHead.appendChild(oScript);
    // 超时函数,请求超时走error逻辑
    if (options.timeout) {
    	oScript.timer = setTimeout(function() {
    		// 错误后清除回调函数
    		window[_callback] = null;
    		oHead.removeChild(oScript);
    		// 执行error函数
    		options.error && options.error({ message: "超时" });
    	}, options.timeout * 1000);
    }
};

// 测试执行
var params = {
	url: 'http://127.0.0.1/jsonp/jsonp.php',
	callback: 'getback',
	timeout: 10,
	data: {
		param1: 'a',
		param2: 'b'
	},
	success: function(data) {
		console.log(data);
	},
	error: function(e) {
		console.log(e);
	}	
}; // 其他参数配置可根据需求添加
jsonp(params);
  1. 后台文件jsonp.php写法
<?php
	// 要返回的数据
	$data = '{
		"shuju1" : "1",
		"shuju2" : "2",
		"shuju3" : "3",
		"shuju4" : "4",
		"shuju5" : "5"
	}';

	// 获取请求传过来的值,用于定义要返回的回调函数名,
	$callback = $_GET['callback']; // 中括号里的'callback',必须和前端ajax里的的jsonp:"callback",中jsonp的值名字一样

	// 将回调函数名和数据拼接成函数的形式。数据以入参的形式传入。
	echo $callback . "(" . $data . ")";
?>
1、一个众所周知的问题,Ajax直接请求普通文件存在无权限访问的问题,甭管你是静态页面、动态网页、web服务、WCF,只要是请求,一律不准;   2、不过我们又发现,Web页面上调用js文件时则不受是否的影响(不仅如此,我们还发现凡是拥有”src”这个属性的标签都拥有的能力,比如[removed]、、<iframe>);   3、于是可以判断,当前阶段如果想通过纯web端(ActiveX控件、服务端代理、属于未来的HTML5之Websocket等方式不算)访问数据就只有一种可能,那就是在远程服务器上设法把数据装进js格式的文件里,供客户端调用和进一步处理;   4、恰巧我们已经知道有一种叫做JSON的纯字符数据格式可以简洁的描述复杂数据,更妙的是JSON还被js原生支持,所以在客户端几乎可以随心所欲的处理这种格式的数据;   5、这样子解决方案就呼之欲出了,web客户端通过与调用脚本一模一样的方式,来调用服务器上动态生成的js格式文件(一般以JSON为后缀),显而易见,服务器之所以要动态生成JSON文件,目的就在于把客户端需要的数据装入进去。   6、客户端在对JSON文件调用成功之后,也就获得了自己所需的数据,剩下的就是按照自己需求进行处理和展现了,这种获取远程数据的方式看起来非常像AJAX,但其实并不一样。   7、为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值