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标签,插入到文档中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)})

服务端返回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头浏览器才会执行  }