JSONP是什么
JSONP(JSON with Padding)是一种跨域数据请求技术,它允许网页在不受同源策略限制的情况下从其他域中请求数据。JSONP的原理是利用 <script> 标签的跨域特性,通过 <script> 标签,指向包含 JSON 数据的远程地址,并在请求的 URL 中传递一个回调函数名,服务端接收到请求后,将数据包装在该回调函数中,返回给客户端,客户端通过回调函数接收并处理返回的数据。由于script 标签的 src 属性,只能使用 get 请求。
举个例子如下:
<!-- www.a.com -->
<script>
function cbData(data) {
console.log("data", data);
}
</script>
<script src="http://www.b.com/api/jsonp?callback=cbData"></script>
// 请求返回的大致内容如下
cbData(参数);
a网页注册了个cbData的函数,在script跨域请求b网的接口增加一个callback参数,值为cbData,请求后,b生成一个函数调用的形式,函数名是callback的值cbData,再将数据以入参的方式给到cbData函数,这样生成了一个js语法的文档返回给a,a拿到后解析运行,相当于执行之前已经定义好的函数 cbData,参数就是传来的数据。
express 实例
const express = require('express');
const app = express();
const port = 3000;
app.get('/api/jsonp', (req, res, next) => {
const callback = req.query.callback
const data = JSON.stringify( { name: 'jiawei', age: 18 } )
res.send(`${callback}(${data});`)
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
新建一个html页面如下,在浏览器中访问。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>JSONP</title>
</head>
<body>
<script>
function cbData(data){
console.log("data", data);
}
</script>
<script src="http://localhost:3000/api/jsonp?callback=cbData"></script>
</body>
</html>
也可以通过js来创建script。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>JSONP</title>
</head>
<body>
<script>
function cbData(data) {
console.log("data", data);
}
var script = document.createElement("script")
script.src = "http://localhost:3000/api/jsonp?callback=cbData"
document.body.appendChild(script)
</script>
</body>
</html>
express 也提供了一个 req.jsonp() ,将 get 修改如下。
app.get('/api/jsonp', (req, res, next) => {
res.jsonp({ name: 'jiawei', age: 18 })
})
默认情况下,JSONP回调名为callback。可以设置 "jsonp callback name" 覆盖此值。
app.set('jsonp callback name', 'cb')
app.get('/api/jsonp', (req, res, next) => {
res.jsonp({ name: 'jiawei', age: 18 })
})
再修改请求链接,运行。
http://localhost:3000/api/jsonp?callback=cbData
// 修改(将callback改为cb)
http://localhost:3000/api/jsonp?cb=cbData