原生js实现JSONP
Table of Contents
介绍
JSONP是JSON with Padding(填充式JSON或参数式JSON)的简写,是一种非常常用的跨域请求方式。主要原理是利用了script
标签可以跨域请求的特性,由其 src
属性发送请求到服务器,服务器返回JavaScript
代码,浏览器接受响应,然后就直接执行了,这和通过 script
标签引用外部文件的原理是一样的。
JSONP由两部分组成:回调函数
和数据
,回调函数是当响应到来时应该在页面中调用的函数,回调函数的名字一般在请求中指定。当服务器响应时,服务器端就会把该函数和数据拼成字符串返回。
JSONP 的请求过程
- 请求阶段:浏览器创建一个
script
标签,并给其src
赋值(类似http://example.com/api/?callback=jsonpCallback
)。 - 发送请求:当给
script
的src
赋值时,浏览器就会发起一个请求。 - 数据响应:服务端将要返回的
数据
作为参数和函数名称
拼接在一起(格式类似”jsonpCallback({name: 'abc'})
”)返回。当浏览器接收到了响应数据,由于发起请求的是script
,所以相当于直接调用jsonpCallback
方法,并且传入了一个参数。
服务端交互示意图
server1代码(Nodejs实现)
var Koa = require('koa');
var Router = require('koa-router');
var querystring = require('querystring');
var app = new Koa();
var router = new Router();
//处理get请求
router.get('/get', async function(ctx){
var params = querystring.parse(ctx.request.url.split('?')[1]);
var data = { message: "我是" + ctx.request.header.host + ",我收到了你的get请求!!!" }
ctx.status=200;
ctx.body=params['callback']+'('+JSON.stringify(data)+');';
});
app
.use(router.routes())
.use(router.allowedMethods())
app.listen(3000);
server2代码
var Koa = require('koa');
var Router = require('koa-router');
var render = require('koa-art-template');
var path = require('path');
var app = new Koa();
var router = new Router();
//配置模板引擎
render(app, {
root: path.join(__dirname, 'views'),
extname: '.html',
debug: process.env.NODE_ENV !== 'production',
});
router.get('/index.html', async function (ctx) {
await ctx.render('server2');
});
app.use(router.routes()).use(router.allowedMethods());
app.listen(4000);
前端代码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>原生js实现</title>
</head>
<body>
<div><button>点击我发送get请求</button></div>
<!-- <script>
function jsonpcallback(response){
alert(response.message);
}
</script>
<script src="http://127.0.0.1:3000/get?callback=jsonpcallback" type="text/javascript"></script> -->
</body>
<script>
document.getElementsByTagName('button')[0].addEventListener('click', function () {
ajax('http://127.0.0.1:3000/get', function(response){
alert(response.message);
});
});
function ajax(url, callback){
var jsonp=document.createElement('script');
jsonp.type = 'text/javascript';
jsonp.src=url+'?callback=jsonpcallback';
jsonpcallback = function(response){
callback(response);
};
document.getElementsByTagName('head')[0].appendChild(jsonp);
}
</script>
</html>
分析
其实上述过程可以总结为:
function jsonpcallback(response){
alert(response.message);
}
jsonpcallback({"message":"我是127.0.0.1:3000,我收到了你的get请求!!!"});