JSONP的实现方式以及相关知识点

JSONP

Posted by gomyck on June 23, 2019

带你理解jsonp的实现思路以及其中原理

Jsonp的应用场景: 需要跨域访问远程服务, 有时可能还需要接收远程服务的响应报文

名词解释:

Json:

一种数据组织格式

Jsonp:

客户端与服务端双方约定传递数据的方法, 也是一种非官方解决跨域问题的野路子

同源:

两个uri A和B , 如果A与B的 请求协议 域名 端口 都相同, 则A与B同源

1
2
3
4
5
6
7
8
9
10
exp:
http://blog.gomyck.com/show/hello.html
协议: http
域名: blog.gomyck.com
端口: 80 (默认端口省略)
http://blog.gomyck.com/goto/welcome.html        同源
http://www.gomyck.com/goto/welcome.html         不同源 (域名不同)
http://im.www.gomyck.com/goto/welcome.html      不同源 (域名不同)
http://blog.gomyck.com:8080/goto/welcome.html   不同源 (端口不同)
https://blog.gomyck.com/goto/welcome.html       不同源 (协议不同)

同源策略约束了网页之间的数据权限以及请求权限, 同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

如果没有同源策略, 用户在浏览A网站的时候, 在登录时选择记住用户名密码, 假设A网站的用户名密码存储在cookie中, 那么当用户访问B网站时, B网站就可以获取A网站的Cookie信息, 造成用户的信息泄漏

跨域请求:

接着同源的AB , 如果A与B不同源, 那么在其中一个uri所指向的页面中, 像另外一个uri发送请求, 都称为跨域请求

——-实现篇——-

在早期项目开发时, 因为客户端服务端对跨域的支持不太完善, 造成标准的(官方)跨域请求兼容性差, 所以在工程师的奇思妙想中, jsonp诞生了, 它极大程度上解决了跨域请求的问题, 以下为个人对jsonp的实现思路整理

整体来说, jsonp钻了个空子: script标签没有同源策略限制

1.假如现在网页上需要使用某一个js组件, 有两种方式:

可以下载到本地, 在本地引入 可以直接引入远端js文件

2.引入的js文件不管是本域还是跨域, 都可以在当前页面执行window.onload或者其他init函数

3.jsonp恰好应用这一点

1
2
假设当前域: www.gomyck.com/exp
目标域: blog.gomyck.com/get/userInfo

在页面编码阶段事先在js文件中编写如下函数:

1
2
3
function getUserInfo(userInfo){
  alert(userInfo)
}

在需要跨域请求时, 使用dom命令动态的操作页面dom, 在页面上新增一个JavaScript标签

1
<script src="blog.gomyck.com/get/userInfo?callBack=getUserInfo"></script>

注意传参: ?callBack=getUserInfo

因为script标签没有同源策略限制, 所以这个js标签的请求会正常发送出去, 而且在页面内当做JavaScript返回并编译

请求发送到blog.gomyck.com后台处理的时候, 根据对应的handler和请求参数, 把返回的报文按照下面的格式封装:

1
getUserInfo("{userName: '张三', age: '李四'}");

当script标签的请求返回响应报文时, 报文格式当做js操作被调用, 调用本页面的同名函数(编码阶段组织好的), 传入变量, 得到用户信息 这样一个完整的跨域请求就结束了

jsonp的优点:

解决跨域问题且数据格式不需要做改变

jsonp的缺点:

只能是get请求, 请求参数长度收到限制 请求参数都附加在url中, 容易被截获 服务端只能通过传参来获取session信息