5

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

 2 years ago
source link: https://www.fly63.com/article/detial/11919
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

更新日期: 2022-07-20阅读: 8标签: jsonp分享

扫一扫分享

介绍: 

有时候请求某些第三方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>
来自:https://www.cnblogs.com/maxiansheng/archive/2022/07/20/16496750.html

链接: https://www.fly63.com/article/detial/11919


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK