先上段简单的代码:
HTML:
<html>
<body>
<script>function yooo(data) {console.log(data)}</script>
<script src="http://127.0.0.1:18888/?callback=yooo" />复制代码
Nodejs:
const http = require('http')
const url = require('url')
const data = {hello: 'world'}
http.createServer((req, res) => {
const params = url.parse(req.url, true)
res.end( params.query.callback + '(' + JSON.stringify(data) + ')' )
}).listen(18888)
复制代码
把这些翻译成人话:
一开始HTML里的js代码是这样的
function yooo(data) { console.log(data) }
复制代码
然后解析到第二个<script>
时,就会向Node发起请求,然后Node返回了'yooo({"hello", "world"})'
这个字符串。经浏览器解析后,HTML里的js代码就变成了这样:
function yooo(data) { console.log(data) }
yooo({"hello", "world"})
复制代码
这个执行结果就很显然了吧,console里打印出{"hello", "world"}
没错,这就是jsonP的核心原理,就是这么简单。把数据包装在一个函数的参数里,然后传给浏览器,让浏览器执行这个函数(wrap data as an argument for a function, pass it to the browser, and then browser execute the function)
//总是说不明白中文术语。。。还是英文术语顺口些
回到jsonP这个名字本身,P -> Padding,这个padding指的就是包在json外面的'yooo('
和 ')'
现在你应该看得懂别人写的jsonP文章了,无非就是把上述东西包装成一个loadJSON函数,执行它的时候能自动给DOM插入个<script src="...?callback=xxx">
,并且将这个xxx callback函数挂载到DOM上,比如window.xxx = xxx
,这样子就可以在全局scope中执行xxx(data)了。
对了,最近在学习webpack4的时候发现,dynamic import其实也是用jsonP实现的。。。有兴趣的童鞋可以玩一下