jsonp
的核心原理是利用script
标签没有同源限制的方式,可以发送跨域的get
请求(只能发送get
请求)。script
标签中的src
属性将请求参数和当前请求的回调函数名拼接在链接上。最终由服务端接收到请求之后拼接成前端可执行的字符串的形式返回。这个结果字符串最终会在前端的script标签中解析并执行。
利用<script>
标签没有跨域限制的漏洞,网页可以得到从其他来源动态产生的JSON
数据。JSONP
请求一定需要对方的服务器做支持才可以。
JSONP
和AJAX
对比: JSONP
和AJAX
相同,都是客户端向服务端发送请求,从服务端获取数据的方式。但AJAX
属于同源策略,JSONP
属于非同源策略(跨域请求)。JSONP
优缺点: JSONP
优点是简单兼容性好,可用于解决主流浏览器的跨域数据访问的问题。缺点是仅仅支持get
方法具有局限性,不安全,可能会遭受XSS
攻击。jsonp
回调函数的名称callbackName
拼接到src
上script
标签,设置它的src
属性callbackName
回调函数,等待script
标签请求结束,并调用 /**
* jsonp获取请求数据
* @param {object}options
*/
function jsonp(options) {
// console.log(options);
// 1. 产生不同的函数名(函数名随机)
let callBackName = 'itLike' + Math.random().toString().substr(2)+Math.random().toString().substr(2);
// console.log(callBackName);
// 2. 产生一个全局函数
window[callBackName] = function (params) {
// console.log(params);
// console.log(options.success);
if(params !== null){
options.success(params);
}else{
options.failure(params);
}
// 2.1 删除当前脚本标签
scriptE.remove();
// 2.2 将创建的全局函数设为null
window[callBackName] = null;
};
// 3. 取出url地址
let jsonpUrl;
if(options.data !== undefined){
jsonpUrl = options.url + '?' + options.data + '&callBack=' + callBackName;
}else {
jsonpUrl = options.url + '?callBack=' + callBackName;
}
// console.log(jsonpUrl);
// 4. 创建script标签
let scriptE = document.createElement('script');
scriptE.src = jsonpUrl;
document.body.appendChild(scriptE);
}
服务端(express)
router.get('/api/v1', function(req, res, next) {
res.json({
'name': '前端收割机',
'address': '广东',
'intro': '前端技术交流公众号'
});
});
调用jsonp
btn.addEventListener('click', ()=>{
jsonp({
url: 'http://localhost:3000/api/v1',
data: 'name=前端收割机&age=20',
success: function (data) {
console.log(data);
},
failure:function(data){
console.log(数据请求失败);
}
});
});
show
)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data
)<script src=>
标签 ,把那个跨域的API
数据接口地址,赋值给script
的src
, 还要在这个地址中向服务器传递该函数名(可以通过问号传参?callback=show
)。show
,它准备好的数据是 show('前端收割机')
。HTTP
协议返回给客户端,客户端再调用执行之前声明的回调函数(show
),对返回的数据进行操作。/**
* jsonp获取请求数据
* @param {string}url
* @param {object}params
* @param {function}callback
*/
function jsonp({ url, params, callback }) {
return new Promise((resolve, reject) => {
let script = document.createElement('script');
params = JSON.parse(JSON.stringify(params));
let arrs = [];
for (let key in params) {
arrs.push(`${key}=${params[key]}`);
}
arrs.push(`callback=${callback}`);
script.src = `${url}?${arrs.join('&')}`;
document.body.appendChild(script);
window[callback] = function (data) {
resolve(data);
document.body.removeChild(script);
}
})
}
服务器(express
)
// 后端响应
// 这里用到了 express
var express = require('express');
var router = express.Router();
var app = express();
router.get('/say',function(req,res,next) {
//要响应回去的数据
let data = {
username : 'zs',
password : 123456
}
let {wd , callback} = req.query;
console.log(wd);
console.log(callback);
// 调用回调函数 , 并响应
res.end(`${callback}(${JSON.stringify(data)})`);
})
app.use(router);
app.listen(3000);
调用jsonp
// 前端调用
btn.addEventListener('click', ()=>{
jsonp({
url: 'http://localhost:3000/say',
params: {
wd: '前端收割机'
},
callback: 'show'
}).then(data => {
console.log(data)
});
});
基本原理:利用 script
标签的 src
没有跨域限制来完成实现。
优缺点:只能 GET
;兼容性好。
简单实现:通过 url, params, callback
来定义 JSONP()
方法的参数。
参考连接:https://juejin.cn/post/6844904094973296654#heading-5
struts json 类型异常返回到js弹框问题解决办法 当struts 框架配置了异常时 例如...
微软官方博客于 2 月初再次发布提示,将会在 3 月 9 日停止对经典版 Edge 浏览器...
在 2021 年,人们喜欢 Linux 的理由比以往任何时候都多。在这个系列中,我将分享...
php实现微信支付 微信支付文档地址: https://pay.weixin.qq.com/wiki/doc/api/i...
前言 我们在使用ajax异步的提交多选框得到需要操作的对象的id,这时我们可以把每...
六、XML展望 任何一项新技术的产生都是有其需求背景的,XML的诞生是在HTML遇到不...
文章目录 关系数据库 关系数据库简介 关系数据结构及形式化定义 关系 关系模式 ...
下面是ajax代码和Controller层代码,期初以为是后台程序写错了。 $("#sourcefile...
背景 该问题来自某客户,据描述,他们在部署 MySQL 主从复制时,有时候仅在主库...
本文转载自微信公众号「程序员历小冰」,转载本文请联系程序员历小冰公众号。 疫...