介紹: 有時候請求某些第三方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 =https://www.cnblogs.com/maxiansheng/p/ 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 =https://www.cnblogs.com/maxiansheng/p/ 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.uj5u.com/qiye/499898.html
標籤:JavaScript
上一篇:h5常用定位功能封裝
