jsonp解决跨域插件(js、ts)

javascript 文章 2022-07-20 13:35 664 0 全屏看文

AI助手支持GPT4.0

介绍: 有时候请求某些第三方api用nginx做反向代理解决跨域不能满足需求,例如请求百度或者腾讯地图的ip定位接口,该接口会根据请求来源的ip返回该ip地址对应的位置信息,但是若是用ng做了代理或者是后端做接口转发的话实际获取到的ip位置信息是服务器的ip地址,想要直接解析客户端的ip位置信息就必须得从客户端直接调用第三方ip定位接口,但是直接请求第三方接口会出现跨域,这时候就可以使用jsonp来解决这个跨域问题。注意:jsonp只能发送get类型的请求。


jsonp插件地址:https://gitee.com/ml_plugins/jsonp

JS版本:

/**
 * @description 用于解决GET类型请求跨域的jsonp插件
 * @param  url 请求接口地址
 * @param  query 请求入参
 * @author xiao ma ge
 */

export default function jsonp(url, query = {}) {
  return new Promise((resolve, reject) => {
    // 根据时间戳生 + 随机数成一个callback回调名
    const callbackName = `jsonp_${new Date().getTime()}` + `${Math.random().toString().replace(/D/g, '')}`

    // 创建一个script
    const script = document.createElement('script')

    // 字符串拼接生成基本url
    let baseUrl = `${url}${url.indexOf('?') === -1 ? '?' : '&'}callback=${callbackName}`

    // 遍历query对象拼接参数到url后
    for (const item in query) {
      const index = baseUrl.indexOf('?')
      baseUrl += `${index === -1 ? '?' : '&'}${item}=${query[item]}`
    }

    // jsonp核心,通过script的跨域特性发出请求
    script.src = baseUrl

    // 给window添加属性,用于获取jsonp结果
    window[callbackName] = (res) => {
      if (res) {
        resolve(res)
      } else {
        reject('未查询到任何数据')
      }
      // 删除window下属性
      delete window[callbackName]
      // 得到结果后删除创建的script
      document.body.removeChild(script)
    }

    // 动态创建script标记,错误的监听
    script.addEventListener('error', () => {
      delete window[callbackName]
      document.body.removeChild(script)
      reject('请求失败!')
    })

    // 把创建的script挂载到DOM
    document.body.appendChild(script)
  })
}

ts版本:

/**
 * @description 用于解决GET类型请求跨域的jsonp插件
 * @param  url 请求接口地址
 * @param  query 请求入参
 * @author xiao ma ge
 */

declare global {
  interface Window {
    [index: string]: any
  }
}

type queryType = {
  [index: string]: any
}

export default function jsonp(url: string, query: queryType = {}): Promise<any> {
  return new Promise((resolve, reject) => {
    // 根据时间戳生 + 随机数成一个callback回调名
    const callbackName = `jsonp_${new Date().getTime()}` + `${Math.random().toString().replace(/D/g, '')}`

    // 创建一个script
    const script = document.createElement('script')

    // 字符串拼接生成基本url
    let baseUrl = `${url}${url.indexOf('?') === -1 ? '?' : '&'}callback=${callbackName}`

    // 遍历query对象拼接参数到url后
    for (const item in query) {
      const index = baseUrl.indexOf('?')
      baseUrl += `${index === -1 ? '?' : '&'}${item}=${query[item]}`
    }

    // jsonp核心,通过script的跨域特性发出请求
    script.src = baseUrl

    // 给window添加属性,用于获取jsonp结果
    window[callbackName] = (res: any) => {
      if (res) {
        resolve(res)
      } else {
        reject('未查询到任何数据')
      }
      // 删除window下属性
      delete window[callbackName]
      // 得到结果后删除创建的script
      document.body.removeChild(script)
    }

    // 动态创建script标记,错误的监听
    script.addEventListener('error', () => {
      delete window[callbackName]
      document.body.removeChild(script)
      reject('请求失败!')
    })

    // 把创建的script挂载到DOM
    document.body.appendChild(script)
  })
}

vue3中使用示例:

<template>
  <div></div>
</template>

<script lang="ts">
  import jsonp from './utils_ts/jsonp'
  export default {
    name: 'Home',
    setup() {
      /**
       * @description 测试jsonp请求腾讯地图IP定位接口
       */
      jsonp('https://apis.map.qq.com/ws/location/v1/ip', {
        key: '这里填写你的腾讯地图key',
        output: 'jsonp'
      }).then((res) => {
        console.log('🚀 ~ file: index.vue ~ line 14 ~ setup ~ res', res)
      })

      return {}
    }
  }
</script>
<style lang="less" scoped></style>

 

-EOF-

AI助手支持GPT4.0


国内超级便宜服务器

摸鱼人热门新闻聚合

钻级赞助商 我要加入

开发者在线工具

第三方支付技术请加QQ群

相关文章
根据屏幕大小自动修改字体大小的代码
Object.defineProperty方法
模拟Vue实现响应式数据
NodeJS 5分钟 连接 Redis 读写操作
flv.js的追帧、断流重连及实时更新的直播优化方案
随便看看
微信开放平台跟公众平台有什么区别? 3607
怎么添加小程序支付功能? 4516
教育科技公司申请微信支付被拒绝? 4798
微信公众号免300认证教程 5892
小程序已经上线,作为管理员无法在小程序数据助手查看数据? 5299
小程序广告组件通过审核,但是小程序内没有显示广告? 5067
企业微信通讯录账号被管理员误/恶意删除,怎么办? 9568
问题? 9047
如何快速搭建抽奖助手小程序(无需代码知识) 6177
许涛 大哥在吗, 要解冻小程序的时候提示信息主体不一致, 能帮忙看下吗? 7471