jsonp 介绍
jsonp 的作用是利用 <script> 标签没有跨域的限制,从而达到与第三方通讯的目的。
此时 <script> 标签的 src 属性是第三方的 API 地址,这样页面加载的时候,就会请求这个 API 。前后端约定好一个函数,这个函数名会以查询参数的形式传给后台,后台拿到这个函数后,会把数据传给这个函数,然后将这个带有数据的函数回传给前端。
由于 <script> 元素请求的脚本,会直接当作代码运行,这时,只要浏览器定义了这个函数,该函数会立即调用。
使用例子
创建一个文件夹 jsonp-demo,在这个文件夹中创建一个 templates 文件夹,并在 templates 创建index.html 文件,该 html 文件中的 <script> 标签会请求后台的 API ,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>auto complete</title>
</head>
<body>
年龄 <span id="age"></span>
</body>
<script>
function getAge(data) {
document.getElementById('age').innerHTML = data.age;
}
</script>
<script src="http://127.0.0.1:3000/js?call=getAge"></script>
</html>
在 jsonp-demo 目录下创建 server.js ,定义 API 接口用于将数据传给前端,该文件的代码如下:
var http = require('http');
var url = require('url');
http.createServer(function (req, res) {
// 解析 url 参数
var path = req.url.split('?')[0];
if (path === '/js') {
res.writeHead(200, { 'Content-Type': 'text/javascript;charset=utf-8' });
var params = url.parse(req.url, true).query;
// 设置返回的内容
res.end(`${params.call}({
code: 200,
age: 20,
friends: [
{
age: 18,
name: 'tom'
},
{
age: 19,
name: 'bob'
}
]
})`);
} else {
res.end('ok');
}
}).listen(3000, function () {
console.log("OK,访问:localhost:3000");
});
在 jsonp-demo 目录下创建 client.js ,用于返回 html 模板,该文件的代码如下:
var http = require("http");
var fs = require("fs");
var path = require("path");
// 创建服务器
http.createServer(function (request, response) {
// 如果链接的路径是 /index 时,返回的页面的 index 页面
if (request.url === '/index') {
// 使用 path.join 拼接路径
var filePath = path.join(__dirname, "templates", "index.html");
fs.readFile(filePath, function (err, data) {
// 如果出现错误就抛出 err,没出错就把 html 页面返回给浏览器
if (err) {
throw err;
} else {
response.end(data);
}
})
} else {
// 如果不调用 end 其他请求客户端将永远处于等待状态
response.end()
}
}).listen(3100, function () {
console.log("OK,访问:localhost:3100");
});
然后分别用 node 执行 server.js 和 client.js ,之后用浏览器访问 http://127.0.0.1:3100/index,可以发现端口为 3100 的页面成功的访问了 3000 接口。
使用例子的完整代码可在这个仓库中查看