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属性来调用服务端返回的回调函数。

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Git创建远程分支并提交代码到远程分支[通俗易懂]

    Git创建远程分支并提交代码到远程分支[通俗易懂]1、可以通过gitbranch-r命令查看远端库的分支情况如图所示,远程仓库只有一个master分支2、从已有的分支创建新的分支(如从master分支),创建一个dev分支但此时并没有在远程仓库上创建分支如图所示还是只有一个master分支3、建立本地到远端仓库的链接–这样代码才能提交上去使用命令行gitpush–set-…

    2022年6月30日
    47
  • JAVA中字符串常量池和缓冲池理解与作用「建议收藏」

    JAVA中字符串常量池和缓冲池理解与作用「建议收藏」字符串池与常量池是完全不同的两个东西,但是很多地方都喜欢把它们混为一谈,很容易让初学者产生误解,在这里我想好好讨论一下它们。字符串池也可以被称为字符串常量池,我认为这个名称就是产生误解的根源,有些人说着说着就把字符串三个字省略了,只剩下了常量池…所以为了避免误解,我建议在指代字符串对象的缓存池的时候,就直接称之为字符串池1常量池常量池分为两个类型,一是.class文件中静态的常量池,二是.class文件中的静态常量池被加载到JVM中而形成的运行时常量池。1.1静态常量池.cla

    2022年7月28日
    8
  • 深度学习之:什么是流形(manifold)?流形空间,流形学习

    深度学习之:什么是流形(manifold)?流形空间,流形学习作者:麋路链接:https://www.zhihu.com/question/24015486/answer/194284643来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。流形学习的观点是认为,我们所能观察到的数据实际上是由一个低维流形映射到高维空间上的。由于数据内部特征的限制,一些高维中的数据会产生维度上的冗余,实际上只需要比较低的维度就能唯一地表示。举个例子,比如说我们在平面上有个圆,如何表示这个圆呢?如果我们把圆放在一个平面直角坐标系中,那一个圆实际.

    2025年7月2日
    5
  • Hough变换-理解篇

    Hough变换-理解篇霍夫变换 HoughTransfo 是图像处理中的一种特征提取技术 它通过一种投票算法检测具有特定形状的物体 该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换结果 霍夫变换于 1962 年由 PaulHough 首次提出 53 后于 1972 年由 RichardDuda 和 PeterHart 推广使用 54 经典霍夫变换用来检测图像中的直线 后来霍夫变换

    2025年10月18日
    3
  • PHP 浏览器缓存_php缓存引擎

    PHP 浏览器缓存_php缓存引擎浏览器缓存动态内容,缓存的内容在浏览器本地,而内容由web服务器生成,任何一方都不可能完成这一系列过程,他们之间有一种沟通机制,这就是缓存协商.如何协商当浏览器向web服务器请求内容时,服务器需要告诉浏览器那些内容可以被缓存,一旦浏览器知道某个内容可以缓存后,下次当浏览器需要请求这个内容时,它便不会直接向服务器请求完整内容,而是询问服务器是否可以使用本地的缓存,服务器在收到浏览器的询问后需要作…

    2022年10月9日
    4
  • statement和prepareStatement 的区别

    statement和prepareStatement 的区别????Java基础教程系列:Java基础教程系列????Java学习路线总结:搬砖工逆袭Java架构师????Java经典面试题大全:10万字208道Java经典面试题总结(附答案)????简介:Java领域优质创作者????、CSDN哪吒公众号作者✌、Java架构师奋斗者????????扫描主页左侧二维码,加入群聊,一起学习、一起进步????欢迎点赞????收藏⭐留言????一、【粉丝福利】送书啦,大家期待已久的Vue!本次活动送书规则:【送

    2022年6月12日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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