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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • CentOS 7 yum安装与配置 Tomcat「建议收藏」

    CentOS 7 yum安装与配置 Tomcat「建议收藏」CentOS7yum安装TomcatCentOS7yum安装Tomcat1、准备工作Tomcat2、安装Tomcat3、配置环境变量4、启动Tomcat和无法访问原因4.1、不能访问的原因5、安装Tomcat管理包6、配置TomcatWeb管理界面7、访问Web界面1、准备工作Tomcat检测本机是否安装Tomcatsystemc…

    2022年5月22日
    139
  • HashMap遍历以及遍历顺序[通俗易懂]

    HashMap遍历以及遍历顺序[通俗易懂]HashMap遍历以及遍历顺序HashMap是Java语言中一种键值对(key-value)数据结构,但不记录key的插入顺序,如果要按照插入顺序进行遍历,则需要使用LinkedHashMap类型。本文将介绍下HashMap的三种遍历方式,LinkedHashMap遍历方式相同!(在leetcode12.整数转罗马数字题目中使用到HashMap遍历,遂做此记录!)HashMap结构定义如下:Map<Integer,String>map=newHashMap<Inte

    2025年10月15日
    3
  • Git指令大全[通俗易懂]

    Git指令大全[通俗易懂]转自:https://mp.weixin.qq.com/s/sF-cx2ss4haO74K55Sjf9g配置首先是配置帐号信息ssh-Tgit@github.com#登陆github修改项目中的个人信息gitconfig–globaluser.name“githelper”gitconfig–globaluser.emailgithelper@gmail.c

    2022年5月7日
    42
  • lsof命令无效

    lsof命令无效1.问题描述在centos下,无法使用命令lsof,出现以下信息:[plain] viewplain copy# lsof -i:3690  -bash: lsof: command not found  2.解决方法我们可以通过yum来安装:[plain] viewplain copy# yum install lsof  本人操作如下:[plain] viewplain copy

    2025年6月7日
    5
  • 小记录

    小记录

    2022年4月3日
    37
  • 两款实用的DDos攻击工具[通俗易懂]

    两款实用的DDos攻击工具[通俗易懂]两款实用的DDos攻击工具2018-02-22Network•Security865之前为了重现某个bug,需要对网络设备进行ddos攻击测试,同时也是对设备的网络攻击防护功能进行抗压测试。临阵磨枪,google了两款攻击工具,windows平台的hyenae,以及Linux平台的hping3,在此记录一下两者的用法。Hyenaehyenae是在Windows平台上非常好用的一…

    2022年7月27日
    37

发表回复

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

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