先来看一个问题👇
通过script标签可以拿到src链接里面的东西吗?
scr发出的是get请求
src链接里的东西需要分情况,一是为了加载外部数据,另一个是为了执行脚本代码。
1. 数据加载(外部数据)
JSONP
是一种常用模式,需要服务端返回一个函数调用包裹着数据,这个函数需要预先在页面中定义。例如:
<script>
function handleData(data) {
console.log("Loaded data:", data);
}
</script>
<script src="http://example.com/data?callback=handleData"></script>
在这个例子中,http://example.com/data
应该返回如 handleData({"key": "value"})
的内容。
2. 执行脚本代码
脚本代码加载后直接使用即可,,无需手动“拿”内容。例如,如果你的script.js
文件定义了函数doSomething()
,加载后可以直接调用:
<script src="script.js"></script>
<script>
doSomething();
</script>
前端接口跨域请求是老生常谈的话题。(不讲跨域通信)
通俗的讲,jsonp就是前端通过get请求,从服务端拿回了一个全局函数包括的json字符串,前端调用服务端返回的全局函数,拿到服务端返回的json作为参数。
接口获取外部数据(GET)
最近遇到一个调用外部数据的跨域问题,上面说过获取外部数据常用的就是jsonp,但是第三方的接口不友好,没有实现jsonp的回调逻辑,第三方不想改动。我的前端静态页面放在tomcat服务上,没法做接口的反向代理,也不想增加nginx代理服务。
两边都不想改,但是这样就无解了吗?非也!
跨域请求只是针对浏览器,后端发出的请求是不受跨域控制的,我们可以在自己的后端服务上写个接口A调用外部数据的接口B,然后前端调用我们自己服务的接口A,这样一来就把跨域问题转化到自己的服务上了,跨域问题就迎刃而解了。
jsonp跨域
实现jsonp的接口
https://www.kongfz.com/getModuleData?callback=test&moduleId=100&_=1717551687647
https://www.kongfz.com/getModuleData?moduleId=100&_=1717551687647
http://suggestion.baidu.com/su?wd=w
孔夫子旧书网这个做的兼容jsonp,很友好,加一个callback参数就可以。如果加了自定义的callback参数,就在返回体外面包一层,然后前端就可以在回调方法里取出来数据。
注意:jsonp要防止跨站脚本攻击(XSS)
通过 script
标签加载外部数据
function loadScript(url, func) {
var head = document.head || document.getElementByTagName('head')[0];
var script = document.createElement('script');
script.src = url;
script.onload = script.onreadystatechange = function() {
if (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') {
func();
script.onload = script.onreadystatechange = null;
}
};
head.insertBefore(script, head.children[0]);
}
// window.baidu = {
// sug: function(data) {
// console.log('data===', data);
// }
// }
// 自定义回调函数,获取接口返回数据
function test(data) {
console.log('data====', data);
}
loadScript('https://www.kongfz.com/getModuleData?callback=test&moduleId=100&_=1717551687647', function() {
console.log('loaded==========')
});
使用 ajax
调用外部数据
前端:
$.ajax({
url: 'http://127.0.0.1:8001/list',
method: 'get',
dataType: 'jsonp', //=>执行的是JSONP的请求,这是jquery封装的ajax的功能
success: res => {
console.log(res);
}
});
服务端:
let express = require('express'),
app = express();
app.listen(8001, _ => { // 监听8001端口
console.log('OK!');
});
app.get('/list', (req, res) => {
let {
callback = Function.prototype // callback如果没有,默认为空的函数
} = req.query;
let data = {
code: 0,
message: '返回jsonp请求的结果'
};
res.send(`${callback}(${JSON.stringify(data)})`); //=>后端需要处理好这样的数据格式
});
Jsonp需要后端支持
图片来源网络
我是 甜点cc,个人网站: home.i-xiao.space/vuepress-st…
升级打怪超厉害!
公众号:【看见另一种可能】