一句话总结:jsonp是实现前端跨域请求的常用方案,其内部原理是利用script标签来进行跨域请求(只能get),这里写下完整实现
// 根据回调函数,重新创建随机的全局函数,避免全局函数管理冲突
function creatCallFun(fn){
var callbackName = randomStr(10) // 随机生成字符串名称
window[callbackName] = function(args){
fn.call(null, args)
}
return callbackName
}
// 参数转化
function creatScriptQuery(url, params){
var querys = [];
for(let key in params){
querys.push(key+'='+params[key])
}
return 'url?'+querys.join('&')
}
// 随机生成规定长度的随机字符串,这里用来生成随机的函数名
function randomStr(len){
var codes = 'abcdefghijklmnopqrstuvwxyz';
var l = len, s='';
while (l>0){
s += codes[Math.floor(Math.random() * codes.length)]
l--
}
return s
}
// 动态创建script标签,插入到文档中,完成http请求
function loadScript(url, params, callfn){
var script = document.createElement('script');
var path = creatScriptQuery(url, params);
var callbackName = creatCallFun(callfn) // 生成随机回调函数名,避免全局污染
script.src = path + '&callback=' + callbackName;
document.body.appendChild(script)
script.onload = function(){
window[callbackName] = null; // 请求完成后函数销毁
// 还要将script消除
}
}
函数调用发送一个请求
loadScript('http://127.0.0.1:7001/test',
{name: 123}, // 请求参数
function(data){ // 回调函数
console.log(data)
})
nodejs 服务端返回callback函数包裹的数据
// @router(/test)
async index() {
const { ctx } = this;
let query = ctx.query
ctx.body = query.callback + '(' + JSON.stringify({ success: false }) +')';
ctx.set('content-type', 'text/javascript'); // 设置header头浏览器才会执行
}
我自己项目中就是这样使用
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。