一句话总结: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头浏览器才会执行
  }

我自己项目中就是这样使用


_AN_
346 声望56 粉丝

Stay out of your comfort zone!