跳到主要内容

JSONP 实现

原生 koa2 实现 jsonp

demo 地址

https://github.com/ChenShenhai/koa2-note/blob/master/demo/jsonp/

具体原理

// 判断是否为JSONP的请求
if (ctx.method === 'GET' && ctx.url.split('?')[0] === '/getData.jsonp') {
// 获取jsonp的callback
let callbackName = ctx.query.callback || 'callback';
let returnData = {
success: true,
data: {
text: 'this is a jsonp api',
time: new Date().getTime()
}
};

// jsonp的script字符串
let jsonpStr = `;${callbackName}(${JSON.stringify(returnData)})`;

// 用text/javascript,让请求支持跨域获取
ctx.type = 'text/javascript';

// 输出jsonp字符串
ctx.body = jsonpStr;
}

解析原理

  • JSONP 跨域输出的数据是可执行的 JavaScript 代码
    • ctx 输出的类型应该是'text/javascript'
    • ctx 输出的内容为可执行的返回数据 JavaScript 代码字符串
  • 需要有回调函数名 callbackName,前端获取后会通过动态执行 JavaScript 代码字符,获取里面的数据

完整 demo 代码

const Koa = require('koa');
const app = new Koa();

app.use(async ctx => {
// 如果jsonp 的请求为GET
if (ctx.method === 'GET' && ctx.url.split('?')[0] === '/getData.jsonp') {
// 获取jsonp的callback
let callbackName = ctx.query.callback || 'callback';
let returnData = {
success: true,
data: {
text: 'this is a jsonp api',
time: new Date().getTime()
}
};

// jsonp的script字符串
let jsonpStr = `;${callbackName}(${JSON.stringify(returnData)})`;

// 用text/javascript,让请求支持跨域获取
ctx.type = 'text/javascript';

// 输出jsonp字符串
ctx.body = jsonpStr;
} else {
ctx.body = 'hello jsonp';
}
});

app.listen(3000, () => {
console.log('[demo] jsonp is starting at port 3000');
});

访问http://localhost:5000/getData.jsonp

koa-jsonp 中间件

demo 地址

https://github.com/ChenShenhai/koa2-note/blob/master/demo/jsonp-use-middleware/

简单例子

const Koa = require('koa');
const jsonp = require('koa-jsonp');
const app = new Koa();

// 使用中间件
app.use(jsonp());

app.use(async ctx => {
let returnData = {
success: true,
data: {
text: 'this is a jsonp api',
time: new Date().getTime()
}
};

// 直接输出JSON
ctx.body = returnData;
});

app.listen(5000, () => {
console.log('[demo] jsonp is starting at port 3000');
});