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)
blank

相关推荐

  • hashmap线程不安全问题_什么是线程安全和线程不安全

    hashmap线程不安全问题_什么是线程安全和线程不安全我们都知道HashMap是线程不安全的,在多线程环境中不建议使用,应该使用ConcurrentHashMap,但是其线程不安全体现在什么地方,可能并没有深入理解,本文将对该问题进行解密。

    2022年10月11日
  • kfold交叉验证_SPSS交叉验证法

    kfold交叉验证_SPSS交叉验证法一、前言在机器学习建模过程中,通行的做法是将数据分为训练集和测试集。测试集是与训练独立的数据,完全不参与训练,用于最终模型的评估。在训练过程中,经常会出现过拟合的问题,就是模型可以很好的匹配训练数据,却不能很好在预测训练集外的数据。如果此时就使用测试数据来调整模型参数,就相当于在训练时已知部分测试数据的信息,会影响最终评估结果的准确性。通常的做法是在训练数据再中分出一部分做为验证(Validation)数据,用来评估模型的训练效果。验证数据取自训练数据,但不参与训练,这样可以相对客观的评估模型对于训

  • Ubuntu 卸载postgresql「建议收藏」

    Ubuntu 卸载postgresql「建议收藏」#####1.卸载当前所有Postgresql相关的Package:apt-getremovepostgresql*ThefollowingpackageswillbeREMOVED:postgresql*postgresql-9.1*postgresql-client-9.1*postgresql-client-common*postgresql-common*…

  • 初识lldp协议

    初识lldp协议1、背景:问题:CDN的场景下,同组cache机器规划不规范,额外产生级联带宽,造成级联带宽跑满,导致丢包和速度变慢;愿景:1、平台支持扫描cache机在网络中的物理位置信息,作为cache机规划的依据,避免产生级联带宽;2、支持出口带宽和级联带宽的报警,当出现出口带宽大于级联带宽时,能报警提醒。当前,交换机使用两层交换机堆叠,外网核心下接外网

  • dns url转发_获取url参数的方法

    dns url转发_获取url参数的方法URL转发包括显性转发和隐性转发。 显性转发:访问域名后,转跳到新的自定义URL地址,浏览地址是变化的。 隐性转发:访问域名后,浏览地址是不变的,但网站内容转跳到新的目标网站内容。 DN…

    2022年10月18日
  • Java集合篇:HashMap原理详解(JDK1.7及之前的版本)

    Java集合篇:HashMap原理详解(JDK1.7及之前的版本)

发表回复

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

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