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

  • jsonp解决跨域插件(js、ts)已关闭评论
  • 155 次浏览
  • A+
所属分类:Web前端
摘要

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

介绍: 有时候请求某些第三方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>

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