jsonp的实现原理_jsonp为什么要提供回调函数

jsonp的实现原理_jsonp为什么要提供回调函数前几天看了动脑老师老宋讲的jsonp原理,觉得很受用,现做下笔记。什么是跨域:跨域是浏览器同源策略而产生的,在不同协议,不同端口,不同域名下(以上任意一个不同都算是跨域)的两个服务之间是无法互相访问的。举例:http://www.baidu.com/index.html调用http://www.baidu.com/server.php(非跨域)http

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

前几天看了动脑老师老宋讲的jsonp原理,觉得很受用,现做下笔记。

什么是跨域

跨域是浏览器同源策略而产生的,在不同协议,不同端口,不同域名下(以上任意一个不同都算是跨域)的客服端和服务端之间是无法互相访问的。

举例

http://www.baidu.com/index.html 调用 http://www.baidu.com/server.php (非跨域)

http://www.baidu.com/index.html 调用 http://www.csdn.com/server.php (主域名不同:,跨域)

http://abc.baidu.com/index.html 调用 http://def.baidu.com/server.php (子域名不同:abc/def,跨域)

http://www.baidu.com:8080/index.html 调用 http://www.baidu.com:8081/server.php (端口不同:8080/8081,跨域)

http://www.baidu.com/index.html 调用 https://www.baidu.com/server.php (协议不同:http/https,跨域)

请注意:localhost和127.0.0.1虽然都指向本机,但也属于跨域。

jsonp原理:

先来看下一个例子:用node在本地搭两个服务,一个处理调用html页面(server1端口:8081),一个用来访问服务下的静态资源(server2端口:8082)。代码如下

server1

let express = require('express');

var app = express();

app.get('/index.html',function(req,res){
	res.sendFile(__dirname+'/'+'index.html');
})

var server = app.listen(8081,function(){
		var host = server.address().address;
		var port = server.address().port;
		console.log("应用实例,访问地址为http://%s:%s", host, port);
});

Jetbrains全家桶1年46,售后保障稳定 server2

let express = require('express');

var app = express();

app.get('/',function(req,res){
	res.send('hello word!!!!');
})

app.use(express.static(__dirname));

var server = app.listen(8082,function(){
		var host = server.address().address;
		var port = server.address().port;
		console.log("应用实例,访问地址为http://%s:%s", host, port);
});

这样就可以来访问server1下的index.html文件以及server2下的静态资源了。接下来我在server2下放了个callback.js文件,然后写了alert(‘hello jsonp!!!’),因为两个服务的端口不一样,存在跨域问题,在server1中的index.html是没办法直接访问server2下的callback.js文件的。但是如果我们用script的src来引用确是可以的(<script src=”http://localhost:8082/callback.js”></script>),如下

jsonp的实现原理_jsonp为什么要提供回调函数

没错,jsonp跨域利用的其实就是script的src属性,这个属性不受同源策略影响,可以访问不同服务下的资源。我们来修改下server2下的callback.js文件,如下

callback({
	name:'jsonp',
	server:'server2',
	content:'hello jsonp!!!'
})

然后server1下的index.html这样写

<!DOCTYPE >
<html>
<head>
	<meta charset="utf-8" >
	<title>jsonp 跨域原理</title>
	<style>
		.wrap{ width: 800px; margin: 100px auto;}
	</style>
</head>
<body>
<div class="wrap">
	<h1>jsonp跨域原理。。。</h1>
</div>
<script>
	function callback(data){
		console.log(data);
	}
</script>
<script src="http://localhost:8082/callback.js"></script>
</body>
</html>

然后浏览器访问:localhost:8081/index.html,结果如下

jsonp的实现原理_jsonp为什么要提供回调函数

获取到server2服务端的数据了,这是jsonp的简单原理。

接下来再改进一下,server2下创建一个dada.json的数据,如下:

jsonp的实现原理_jsonp为什么要提供回调函数

然后读取这个文件,并获取客户端传过来的cb参数,然后包裹数据返回给客户端,代码如下:

let express = require('express');
let fs = require('fs');
let url = require('url');
let querystring = require('querystring');

var app = express();

app.get('/',function(req,res){
	res.send('hello word!!!!');
})

app.use(express.static(__dirname));

app.get('/getdata',function(req,res){
	
	//同步读取json文件
	var data = fs.readFileSync('server2/data.json').toString();
	//console.log(data);
	var qs = url.parse(req.url).query;
	var cb = querystring.parse(qs).cb;
	
	var jsonp = cb+"("+data+")";
	res.send(jsonp);
});

var server = app.listen(8082,function(){
		var host = server.address().address;
		var port = server.address().port;
		console.log("应用实例,访问地址为http://%s:%s", host, port);
});


最后在客户端server1的index.html中这样修改:

<!DOCTYPE >
<html>
<head>
	<meta charset="utf-8" >
	<title>jsonp 跨域原理</title>
	<style>
		.wrap{ width: 800px; margin: 100px auto;}
	</style>
</head>
<body>
<div class="wrap">
	<h1>jsonp跨域原理。。。</h1>
</div>
<script>
	function callback(data){
		console.log(data);
	}
	
	var scriptDom = document.createElement('script');
	scriptDom.src = "http://localhost:8082/getdata?cb=callback";
	document.body.appendChild(scriptDom);
	
</script>
<!--<script src="http://localhost:8082/callback.js"></script>-->
</body>
</html>

浏览器访问:localhost:8081/index.html 如下:

jsonp的实现原理_jsonp为什么要提供回调函数

成功获取8082端口下的data.json数据。

结论:

jsonp通过在服务端用一个回调函数把数据一起包裹起来并返回给客户端(jsonp名字就是这样来的json padding),然后客户端写好回调(处理数据),并动态创建一个script节点,通过src属性来调用服务端返回的回调函数。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/206667.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号