博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JSONP的历史方案和实现原理
阅读量:6785 次
发布时间:2019-06-26

本文共 4629 字,大约阅读时间需要 15 分钟。

1. JSONP的实现原理

JSONP是通过动态创建script实现的。

请求方:frank.com 的前端程序员(浏览器)。
响应方:jack.com 的后端程序员(服务器)。
(1).请求方创建 script, src 指向响应方,同时传入一个查询参数 ?calbackName=yyy。
(2).响应方根据查询参数callbackName,构造性如:
    (一).yyy.call(undefined,'你要的数据')
    (二).yyy('你要的数据')
这样的响应。
(3).浏览器接收到响应,就会执行 yyy.call(undefined,'你要的数据')。
(4).那么请求方就知道了他要的数据。
整个过程就是JSONP的实现过程。

2. JSONP相关历史方案

例子:用数据库做加法

一个简易的server服务器
    代码:
做一个点击button,价格减1的demo,没有和数据库进行交互
      代码:

2.1 利用form请求数据

增加数据库文件db.txt,与数据库进行交互

    修改html,利用form表单post方法发送数据,请求路径 /pay,方法 post,点击提交按钮,金额减一。
    新建db.txt,内容为100
    修改db.txt,增加端口'/pay',使得网页每次请求,金额减一。
     效果,点击提交后,点击后退按钮,刷新页面,金额是会减一。
    代码:
修改server.js,添加随机数,让求情可能成功可能失败。
    代码:
    细节:每次点击提交form,页面都会刷新,如何优化?
    古老的方法:利用iframe代替页面刷新
修改index.html,让form的target指向iframe
     代码:
    如何不用iframe?

2.2 利用 image发送请求

不用form创建请求,而利用image来发请求

    创建image,放在内存中,浏览器发现就会立即请求img的source
    修改index.html, 在script标签中创建img元素,并让img.src='./pay',添加img.onload和onerror,根据状态码显示失败或成功
    修改server.js, 删除if条件必须是post,给响应添加状态码,成功响应200,失败响应400
    结果:只能显示失败,重要的的是理解利用image来发请求的思路
    代码:
解决bug,我们并没有如真正的图片所以失败了,只需要给服务器一张真的图片即可(1X1的空白像素)
     这里用随意一张图片代替
    修改server.js,‘./pay’接口的if成功区块

response.setHeader('Content-Type','img/jpg')response.write(fs.readFileSync('./dog.jpg'))复制代码

    代码:

    代码:
修改index.html,打钱成功后,添加window.location.reload()实现请求成功后的自动刷新但这样会重新加载页面,我们需要的是页面局部更新
    修改index.html,删除window.locaiton.reload(),添加amount.innerText = amount.innerText - 1
这样我们在服务器数据更改的同时,页面上显示的数据也实现了更新。
    代码:

2.3 利用script发送请求

利用script发请求

    修改index.html,创建script,script.src等于接口,并且需要将创建的script插入到body中,不然不起作用。
    修改server.js的数据传输类型为 application/javascript
    代码:
每次我们点击提交时,都会新创建一个script标签插入到页面中
    修改server.js,pay接口,成功时写入‘我是pay’
由于页面中出现了script标签,浏览器就会将这个script执行掉,而它里面的内容就是alert('我是pay'),执行完之后再去调用onload事件。
    代码:
修改server.js,去掉响应失败,全部响应成功,如果成功,则弹出对话框‘我是pay’
    代码:
    删除onload,通过response.write对页面数字进行更改,形成比较简洁的方案
    代码:
每次提交都会添加script标签,我们可以删掉

修改index.html,添加script.onload = function(e) {                e.currentTarget.remove()            }复制代码

    代码:

2.4 SRJ

这个方案名:SRJ Server rendered javascript 服务器返回的javascirpt,在ajax出来以前,程序员想出来的,无刷新局部更新页面内容的方案。

2.5 请求另一个网站的script

请求另一个网站的script

两个网站通过SRJ相互访问。
    修改hosts,命令行 vi /etc/hosts ,让frank.com和jack.com等价于127.0.0.1
    修改hosts参考链接https://jingyan.baidu.com/article/b907e627d86be046e6891c41.html
    在最后面添加
    127.0.0.1 frank.com
    127.0.0.1 jack.com
    监听8001端口的网站 命令行 node server.js 8001
    监听8002端口的网站 命令行 node server.js 8002
打开窗口通过,打开frank.com:8001和jack.com:8002,它们是两个不同的网站
     修改index.html,script.src = 'http://jack.com:8002/pay'
    点击8001的打钱按钮,服务器返回的是8002对应服务器的数据。
    代码:
这个方案的缺点,后端对前端的了解太深入了,耦合程度太高,所以需要解耦

修改index.html    window.xxx = function(result) {                if(result === 'success') {                    amount.innerText = amount.innerText - 1                } else {                }            }    script.src = 'http://jack.com:8002/pay?callbackName=xxx'复制代码

修改server.js

${query.callbackName}.call(undefined,'success') 这样来解耦,这样后端不许要知道前端的细节,只需要给结果就行了。
script不受域名限制,ajax受域名限制
    代码:

2.6 JSONP的由来

JSONP的由来,{}左边加左padding,右边叫右padding,简称JSONP。。。。。

也就是JSON+padding=JSONP
如果是String的话,也可以是String + padding = StringP
    代码:

3. JSONP

JSONP

请求方:frank.com 的前端程序员(浏览器)。
响应方:jack.com 的后端程序员(服务器)。
(1).请求方创建 script, src 指向响应方,同时传入一个查询参数 ?calbackName=yyy。
(2).响应方根据查询参数callbackName,构造性如:
    (一).yyy.call(undefined,'你要的数据')
    (二).yyy('你要的数据')
这样的响应。
(3).浏览器接收到响应,就会执行 yyy.call(undefined,'你要的数据')。
(4).那么请求方就知道了他要的数据。
这就是JSONP

3.1 约定

约定:

1.callbackName -> calllback
2.yyy -> 随机数 frank18375912375()
一个符合约定的JSONP
随机数每次调用完,都及时销毁,不占用全局变量
    代码:

3.2 使用jquery实现JSONP

只需要确定url的值,dataType的值是jsopn,响应成功后做什么;不用管后台如何调用。

注意:JSONP不是ajax,只是jquery把JSONP归为ajax的方法里面去了。

button.addEventListener('click', (e)=>{            $.ajax({                url: "http://jack.com:8002/pay",                dataType: "jsonp",                success: function(response) {                    if(response === 'success') {                        amount.innerText = amount.innerText - 1                    }                }            }) })复制代码

这个方法和ajax没关系,它只是简化了JSONP的整个过程

    代码:

3.3 JSOPN误导

1.名字会误导你,让你以为它和JSON有关系

2.jquery会误导你,让你以为它和ajax有关系

4. 面试题

4.1 什么是 JSONP?

JSONP 请求方:frank.com 的前端程序员(浏览器)。

响应方:jack.com 的后端程序员(服务器)。
(1).请求方创建 script, src 指向响应方,同时传入一个查询参数 ?calbackName=yyy。
(2).响应方根据查询参数callbackName,构造性如:
    (一).yyy.call(undefined,'你要的数据')
    (二).yyy('你要的数据')
这样的响应。
(3).浏览器接收到响应,就会执行 yyy.call(undefined,'你要的数据')。
(4).那么请求方就知道了他要的数据。
这就是 JSONP
约定:
    1. callbackName -> callback
    2. yyy -> 随机数 frank12312312312321325()
    3. jQuery 用法

$.ajax({ url: "http://jack.com:8002/pay", dataType: "jsonp", success: function( response ) {     if(response === 'success'){     amount.innerText = amount.innerText - 1     } } })复制代码

4.2 请问 JSONP为什么不支持POST请求(99%)

因为JSONP是通过动态创建script实现的,而动态创建script的时候只能用get没有办法用post。

转载于:https://juejin.im/post/5aca1c50f265da23945fc31a

你可能感兴趣的文章
数组的相关知识
查看>>
Python中的logger和handler到底是个什么鬼
查看>>
mysql之 openark-kit online ddl
查看>>
mydumper安装、原理介绍
查看>>
值类型和引用类型的详细讨论
查看>>
《ArcGIS Runtime SDK for Android开发笔记》——(12)、自定义方式加载Bundle格式缓存数据...
查看>>
mysql 查询当天、本周,本月,上一个月的数据
查看>>
构建和管理有效API市场的关键步骤
查看>>
B00003 C++标准库 std::bitset
查看>>
字符串最小表示法(1) 朴素算法
查看>>
oracle监听问题
查看>>
windows 数据类型转换为 dotnet 数据类型
查看>>
fork函数
查看>>
ROS语音交互——科大讯飞语音合成TTS(二)
查看>>
为什么要架构?当架构走火入魔时怎么办
查看>>
请说明Java中字符'\'的含义,有什么作用?
查看>>
Jenkins部署Python项目实战
查看>>
.Net Core 2.0生态(3):ASP.NET Core 2.0 特性介绍和使用指南
查看>>
数论5——欧拉定理
查看>>
记一次 Confluence 被攻击事件
查看>>