jsonp跨域原理解析

jsonp跨域原理解析背景:由于浏览器同源策略的限制,非同源下的请求,都会产生跨域问题,jsonp即是为了解决这个问题出现的一种简便解决方案。同源策略即:同一协议,同一域名,同一端口号。当其中一个不满足时,我们的请求即会发生跨域问题。举个简单的例子:http://www.abc.com:3000到https://www.abc.com:3000的请求会出现跨域(域名、端口相同但协议不同) http:/…

大家好,又见面了,我是你们的朋友全栈君。

背景:

由于浏览器同源策略的限制,非同源下的请求,都会产生跨域问题,jsonp即是为了解决这个问题出现的一种简便解决方案。

同源策略即:同一协议,同一域名,同一端口号。当其中一个不满足时,我们的请求即会发生跨域问题。

举个简单的例子:

  1. http://www.abc.com:3000到https://www.abc.com:3000的请求会出现跨域(域名、端口相同但协议不同)
  2. http://www.abc.com:3000到http://www.abc.com:3001的请求会出现跨域(域名、协议相同但端口不同)
  3. http://www.abc.com:3000到http://www.def.com:3000的请求会出现跨域(域名不同)

突破同源策略限制:

现在知道了同源策略,那我们就来看下jsonp是如何突破同源策略的限制实现跨域的

首先,不知道大家有没有注意,不管是我们的script标签的src还是img标签的src,或者说link标签的href他们没有被同源策略所限制,比如我们有可能使用一个网络上的图片,就可以请求得到

<img src="https://ss3.baidu.com/9fo3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=6d0bf83bda00baa1a52c41bb7711b9b1/0b55b319ebc4b745b19f82c1c4fc1e178b8215d9.jpg">

src或href链接的静态资源,本质上来说也是一个get请求,拿csdn上的静态资源举例:

jsonp跨域原理解析

可以看到,确实是个get请求无疑。同理img标签的src和link标签的href也会发送一个get请求去请求静态资源。那么我们通过这点,是不是发现了点什么,这些标签的src和link属性,并没有受同源策略的限制。说到这里jsonp的实现原理就浮出水面了。

jsonp就是使用同源策略这一“漏洞”,实现的跨域请求(这也是jsonp跨域只能用get请求的原因所在)。想象一下,既然是个get请求,那么服务端一定可以接收到,并做出反馈。ok,知道这两点之后,我们开始具体使用jsonp进行跨域请求。

JSONP跨域实现:

根据上边所说的,我们要用过利用srcipt标签的src属性来实现,那么我们如何做呢,我们来看一段简单的代码,为了方便,我这里使用jQuery:

$('#btn').click(function(){
			var frame = document.createElement('script');
			frame.src = 'http://localhost:3000/article-list?name=leo&age=30&callback=func';
			$('body').append(frame);
		});

可以看到,让我们点击按钮的时候,创建了一个script标签(即会发送一个get请求到src指向的地址,注意:这里必须使用scipt标签,否则返回的数据不会被当作js执行),src地址是”localhost:3000/article-list”,这个src地址,就是我们请求的服务端接口。注意,这里我们有是那个参数,name,age和callback,name和age不说了,这跟我们平时普通的get请求参数无异。主要说下callback这个参数,callback参数就是核心所在。为什么要定义callback呢?首先我们知道,这个get请求已经被发出去了,那么我们如何接口请求回来的数据呢,callback=func则可以帮我们做这件事。我们继续看下边的代码 

<button id="btn">点击</button>
  <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
  <script>
    $('#btn').click(function(){
			var frame = document.createElement('script');
			frame.src = 'http://localhost:3000/article-list?name=leo&age=30&callback=func';
			$('body').append(frame);
		});
		
		function func(res){
			alert(res.message+res.name+'你已经'+res.age+'岁了');
		}
  </script>

这里可以看到,我们声明了一个func函数,但没有执行,你可以想一下,如果服务端接口到get请求,返回的是func({message:’hello’}),这样的话在服务端不就可以把数据通过函数执行传参的方式实现数据传递了吗。

服务端代码实现:

接下来,我们看服务端应该如何实现:

router.get('/article-list', (req, res) => {
  console.log(req.query, '123');
  let data = {
    message: 'success!',
    name: req.query.name,
    age: req.query.age
  }
  data = JSON.stringify(data)
  res.end('func(' + data + ')');
});

ok,接下来当我们点击提交的时候,就获取到了服务端反回的数据。如下:

jsonp跨域原理解析

这样下来,就完成了实现jsonp的跨域。

总结:

需要注意的是,callback参数定义的方法是需要前后端定义好的,具体什么名字,商讨好就可以了。其实jsonp的整个过程就类似于前端声明好一个函数,后端返回执行函数。执行函数参数中携带所需的数据,整个过程实际非常简单易懂,如有疑问大家可以在下方留言,我会及时回复。

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

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

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


相关推荐

  • mysql shell创建数据库_mysql怎么建立数据库

    mysql shell创建数据库_mysql怎么建立数据库#!/bin/shSHELL_NAME=GetTabStript.sh/bin/rm-fCreateTable.sql/bin/rm-ftmp.sql##获取数据库用户名、密码、实例,属主,表名称列表信息;执行格式如下:##指定表:shGetTabStript.sh”dbrwdadm””dbrwdadm””chnrwd””DBRWDADM””DCUSTMSGSCHNKPI”…

    2022年9月8日
  • 雅虎优化最佳实践

    雅虎优化最佳实践毕竟对于前端来说,优化是躲不开的主题。在看200(cache)和304区别的时候,翻到了雅虎这边归纳出来的准则,虽然是十多年前的东西了吧,但是还是具有参考价值的,因此在原文基础上我进行了一些归纳翻译。原文地址:https://developer.yahoo.com/performance/rules.html减少初始访问的请求数,多使用缓存尽量减少使用的组件种类,因为页面会花很多时间下载组件们。尽…

    2022年7月13日
  • c# 自定义配置文件[通俗易懂]

    c# 自定义配置文件[通俗易懂]c# 自定义配置文件

    2022年4月25日
  • 二叉树abcdefghij先序遍历_二叉树后序遍历的非递归算法

    二叉树abcdefghij先序遍历_二叉树后序遍历的非递归算法给定一个二叉树,判断其是否是一个有效的二叉搜索树。假设一个二叉搜索树具有如下特征:节点的左子树只包含小于当前节点的数。节点的右子树只包含大于当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。题解深搜/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() :

    2022年8月9日
  • acwing-378. 骑士放置(最小独立集)

    acwing-378. 骑士放置(最小独立集)给定一个 N×M 的棋盘,有一些格子禁止放棋子。问棋盘上最多能放多少个不能互相攻击的骑士(国际象棋的“骑士”,类似于中国象棋的“马”,按照“日”字攻击,但没有中国象棋“别马腿”的规则)。输入格式第一行包含三个整数 N,M,T,其中 T 表示禁止放置的格子的数量。接下来 T 行每行包含两个整数 x 和 y,表示位于第 x 行第 y 列的格子禁止放置,行列数从 1 开始。输出格式输出一个整数表示结果。数据范围1≤N,M≤100输入样例:2 3 0输出样例:4#include<b

    2022年8月10日
  • 查看Linux版本

    查看Linux版本

    2021年10月18日

发表回复

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

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