手写jsonp

标签的src属性不受浏览器跨域的限制

  • 要点
    1. 创建script标签
    2. 前端一个全局函数
    3. 服务端返回前端全局函数的调用
function jsonp (url) {
  /*声明一个唯一的回调函数并挂载到全局上
   *创建一个script标签地址 指向 请求服务器 将回调函数名作参数带到服务器
   *服务器拿到回调名称 并返回前端 该回调的调用 把返回结果当作参数传入
   */
  let script = document.createElement('script')
  let uniqueName = `jsonpCallback${new Date().getTime()}`
  script.src = `url${url.indexOf('?') > -1 ? '&': '?'}callback=${uniqueName}`
  document.body.appendChild(script)

  window[uniqueName] = (res) => {
    cb && cb(res)
    document.body.removeChild(script)
    delete window[uniqueName]
  }
}

// 调用
jsonp('getList', (res) => {
  console.log(res)
})


// 服务器端
1. 获取参数, 拿到回调函数名称
2. 返回参数名的前端回调的调用 并 把要返回的参数作为实参调用

/*弊端 - 只支持get请求,并且不安全,需要服务器支持*/

function jsonp ({url, query}) {
  let script = document.createElement("script");
  let cb = `jsonpCallBack${new Date().getTime()}${Math.floor(Math.random(5)*100000)}`
  let params = {...query, cb}

  let arr = []
  for (let key in params) {
    arr.push(`${key}=${params[key]}`)
  }

  script.src = `${url}?${arr.join("&")}`
  document.body.appendChild(script)

  return new Promise((resolve, rej) => {
    window[cb] = function (res) {
      resolve(res)
      document.body.removeChild(script)
      delete window[cb]
    }
  })
}

jsonp({
  url:'/getList',
  query: {name: 'ys',age: 19}
}).then((res) => {
  console.log(res)
})


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容