jsonp的实现原理

news2024/11/24 13:35:05

什么是跨域

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

举例

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);
});

复制

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跨域利用的其实就是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,结果如下

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

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

然后读取这个文件,并获取客户端传过来的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 如下:

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

结论:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/594900.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Springboot +spring security,前后端分离时的security处理方案(一)

一.简介 在前后端分离这样的开发模式下&#xff0c;前后端的交互都是通过 JSON 来进行数据传递的&#xff0c;无论登录成功还是失败&#xff0c;都不会有服务端跳转或者客户端跳转之类的操作。 也就是说无论登录成功还是失败&#xff0c;服务端都会返回一段登录成功或失败的 …

与传统序列化比,PB更快更节省空间

文章目录 为何选择PBPB安装WindowsMac未完待续 语法命令行编译Maven插件编译UDP通信的例子 3大序列化方法对比 为何选择PB 在网络传输和存储数据的时候比传统的 JSON 效果更好 PB安装 GitHub Windows 下载 配置环境变量 验证 Mac未完待续 后续补充Mac安装方式 语法 使用过…

Word、Excel、PPT题库——“办公自动化”

小雅兰期末加油冲冲冲&#xff01;&#xff01;&#xff01; 1.【单选题】下列文件扩展名,不属于Word模板文件的是&#xff08; A &#xff09;。 A. .DOCX B. .DOTM C. .DOTX D. .DOT 本题的考查点是word基本知识的了解。 .DOCX&#xff1a;word文档。 .DOTM&#xff1a;启…

目标检测:RPN — Faster R-CNN 的主干

动动发财的小手&#xff0c;点个赞吧&#xff01; 在使用 R-CNN 的目标检测中&#xff0c;RPN 是真正的主干&#xff0c;并且到目前为止已被证明非常有效。它的目的是提出在特定图像中可识别的多个对象。 这种方法是由 Shaoqing Ren、Kaiming He、Ross Girshick 和 Jian Sun 在…

Pandas 28种常用方法使用总结

Pandas库专为数据分析而设计&#xff0c;它是使Python成为强大而高效的数据分析环境的重要因素。它提供了多种数据结构和方法来处理和分析数据。下面是一些Pandas常用方法的使用总结。 1. 创建数据框 使用read_csv()或read_excel()方法读取数据文件&#xff0c;也可以使用Dat…

饶派杯XCTF车联网安全挑战赛Reverse GotYourKey

文章目录 一.程序逻辑分析二.线程2的operate方法解析三.找出真flag 一.程序逻辑分析 onCreate方法中判断SDK版本是否>27 然后创建两个线程 第一个线程是接受输入的字符串并发送出去 第二个线程用于接受数据 线程1,就是将字符串转为字节数组发送出去 线程2,作为服务端接受…

knife4j、swagger、springdoc 返回接口分组排序问题

一、直击问题 解决前后顺序对比 解决方法&#xff1a; 在配置文件中添加排序规则方法sortTagsAlphabetically&#xff1a; package com.example.demo.config;import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.enums.Security…

OpenMMlab的整体概述和作用

是什么&#xff1f; 开源算法体系&#xff08;非框架、有开源代码&#xff09; 用pytorch实现 优势 开箱即用&#xff0c;复现了很多顶会论文中的算法。每个cv任务对应算法库&#xff0c;其中顺序即为学习路线。便于对比实验。 使用统一的框架、超参数&#xff0c;做对比实…

测试接口遇到APP加密?先来了解一下算法思路~

背景 服务端与客户端进行http通讯时&#xff0c;为了防止被爬虫&#xff0c;数据安全性等&#xff0c;引入APP通信加密&#xff0c;简单来说&#xff0c;就是引入签名sign&#xff0c;APP的所有请求都会经过加密签名校验流程。常见的加密方案有AES加密&#xff0c;RSA加密&…

性能测试1

目录 1.什么是性能测试 1.1性能测试的定义 1.2性能测试和功能测试的区别 1.3影响一个软件性能因素有什么影响 2.为什么是性能测试 3.性能测试常见的术语和性能测试衡量指标 3.1并发用户数 3.2响应时间/平均响应时间&#xff08;RT/ART) 3.3事务响应时间 3.4每秒事务通…

yolov5训练时遇到的问题

torch会自动被requirement.txt替换 在对yolov5_5.0进行pip install requirement.txt后&#xff0c;yolo5_5.0会将虚拟环境中中的torch替换为2.0.1版本的&#xff0c;但要注意查看该torch是否为gpu版本&#xff0c;查看方式如下&#xff1a;打开Anaconda Prompt&#xff0c;激活…

分布式爬虫框架

分布式爬虫框架分为两种&#xff1a;控制模式&#xff08;左&#xff09;和自由模式&#xff08;右&#xff09;&#xff1a; 控制模式中的控制节点是系统实现中的瓶颈&#xff0c;自由模式则面临爬行节点之间的通信处理问题。因此&#xff0c;在实际工程中&#xff0c;我们通常…

go语言命令行工具cobra

go语言命令行工具cobra 1、Cobra 介绍 Cobra 是关于 golang 的一个命令行解析库&#xff0c;用它能够快速创建功能强大的 cli 应用程序和命令行工具。 cobra既是一个用于创建强大现代CLI应用程序的库&#xff0c;也是一个生成应用程序和命令文件的程序。cobra被用在很多 go…

【从球开始渲染小姐姐】DAY1----用blender捏一个小姐姐

Building Blender/Windows - Blender Developer Wikihttps://wiki.blender.org/wiki/Building_Blender/Windows How to build Blender on Windows? - YouTubehttps://www.youtube.com/watch?vb6CtGm4vbng bf-blender - Revision 63388: /trunk/lib/win64_vc15https://svn.b…

DJ4-6 虚拟存储器的基本概念

目录 4.6.1 虚拟存储器的引入 1、常规存储器管理方式的特征 2、内存的扩充方法 4.6.2 局部性原理 4.6.3 虚拟存储器的定义 1、虚拟存储器的基本工作情况 2、虚拟存储器的定义 3、虚拟存储器的实现方法 4.6.4 虚拟存储器的特征 基本分页和基本分段不能解决的问题&a…

snpEFF和bedtools基因注释有何异同?

大家好&#xff0c;我是邓飞&#xff0c;现在写博客越来越繁琐了&#xff0c;每个平台对图片都有自己的规则&#xff0c;不能通用&#xff0c;各种找不到图片&#xff0c;本着充值是我变强的原则&#xff0c;买了Markdown Nice的VIP&#xff08;https://product.mdnice.com/&am…

自然语言处理从入门到应用——自然语言处理(Natural Language Processing,NLP)基础知识

分类目录&#xff1a;《自然语言处理从入门到应用》总目录 自然语言通常指的是人类语言&#xff0c;是人类思维的载体和交流的基本工具&#xff0c;也是人类区别于动物的根本标志&#xff0c;更是人类智能发展的外在体现形式之一。自然语言处理&#xff08;Natural Language Pr…

C Primer Plus第十四章编程练习答案

学完C语言之后&#xff0c;我就去阅读《C Primer Plus》这本经典的C语言书籍&#xff0c;对每一章的编程练习题都做了相关的解答&#xff0c;仅仅代表着我个人的解答思路&#xff0c;如有错误&#xff0c;请各位大佬帮忙点出&#xff01; 由于使用的是命令行参数常用于linux系…

LeetCode:1143.最长公共子序列 1035.不相交的线 53. 最大子序和

1143.最长公共子序列 题目 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除…

字节和滴滴划水5年,总结出来的真实经验....

先简单交代一下背景吧&#xff0c;某不知名 985 的本硕&#xff0c;17 年毕业加入字节&#xff0c;之后跳槽到了滴滴&#xff0c;一直从事软件测试的工作。之前没有实习经历&#xff0c;算是5年的工作经验吧。 这5年之间完成了一次晋升&#xff0c;换了一家公司&#xff0c;有…