介紹: 有時候請求某些第三方api用nginx做反向代理解決跨域不能滿足需求,例如請求百度或者騰訊地圖的ip定位介面,該介面會根據請求來源的ip返回該ip地址對應的位置信息,但是若是用ng做了代理或者是後端做介面轉發的話實際獲取到的ip位置信息是伺服器的ip地址,想要直接解析客戶端的ip位置信息就必 ...
介紹: 有時候請求某些第三方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('