Vue-jsonp

A lightweight JS library for handling JSONP requests sent by vUE.

Install

npm install vue-jsonp -S
Copy the code

usage

    1. Added in main.js to register as a global plug-in for Vue
import { VueJsonp } from 'vue-jsonp'
Vue.use(VueJsonp)
Copy the code

Now you can use this.$jsonp in Vue components to send JSONP requests, because vue. use(VueJsonp) assigns $jsonp to the Vue prototype: Prototype.$jsonp = jsonp

This $json (' https://apis.map.qq.com/ws/place/v1/suggestion ', {region: "hangzhou", keyword: query, the key: "CCWBZ-LZD6S-67COM-6GWDO-CHJ67-*****", output: 'jsonp' }).then(res => { // ... })Copy the code
    1. Use functions directly in components:
The import {json} from 'vue - the json json (' https://apis.map.qq.com/ws/place/v1/suggestion', {region: "hangzhou", keyword: query, key: "CCWBZ-LZD6S-67COM-6GWDO-CHJ67-*****", output: 'jsonp' }).then(res => { // ... })Copy the code
  • Send data and set query parameters & function names
// The request url will be "/some-jsonp-url? name=LancerComet&age=100&callback=jsonp_{RANDOM_STR}". jsonp('/some-jsonp-url', { name: 'LancerComet', age: 100 })Copy the code
  • Custom query and function names
// The request url will be "/some-jsonp-url? name=LancerComet&age=100&cb=jsonp_func". jsonp('/some-jsonp-url', { callbackQuery: 'cb', callbackName: 'jsonp_func', name: 'LancerComet', age: 100 })Copy the code

Partial source code analysis

Vue-jsonp is developed using typescript syntax using rollupJS as a packaging tool. Entry file./lib/index.ts core code is only 185 lines of code, quite concise.

import Vue from 'vue'
import { PluginObject } from 'vue/types/plugin'
import { flatten, formatParams, randomStr } from './utils'

const DEFAULT_TIMEOUT: number = 5000

declare module 'vue/types/vue' {
  // tslint:disable-next-line:interface-name
  interface Vue {
    $jsonp: typeof jsonp
  }
}

/**
 * Vue JSONP.
 */
// tslint:disable-next-line:variable-name
const VueJsonp: PluginObject<never> = {
  install (V: typeof Vue) {
    V.prototype.$jsonp = jsonp
  }
}


// ....
export {
  VueJsonp,
  jsonp
}
Copy the code

Making plug-ins in TypeScript requires type declarations, and the use of TypeScript modules in projects adds module augmentation features, Declare the $JSONp type to be added to the Vue in the Declare Module ‘vue/types/vue’, register the VueJsonp plugin, assign $jsonp to the vue prototype, Mount the jSONp function to vue.prototype. $jsonp.

const VueJsonp: PluginObject<never> = {
  install (V: typeof Vue) {
    V.prototype.$jsonp = jsonp
  }
}
Copy the code

jsonp()

  • The JSONP function creates script tags on the fly and uses script SRC to retrieve data across domains that are not bound by the same origin policy
  • Create a global callback function on the Window object according to the callbackName to receive data, concatenate the request address with the request parameters, and mount it to the Document. Wait for the server to respond and return the agreed data, return a Promise instance,resolve(json)
  • JSONP consists of two parts: callback functions and data. The callback function is the function that should be called in the page when the response arrives. The name of the callback function is usually specified in the request. The data is the JSON data passed into the callback function.
function jsonp<T = any> ( url: string, param: IJsonpParam = {}, timeout? : number ): Promise<T> { if (typeof url ! == 'string') { throw new Error('[Vue-jsonp] Type of param "url" is not string.') } if (typeof param ! == 'object' || ! param) { throw new Error('[Vue-jsonp] Invalid params, should be an object.') } timeout = typeof timeout === 'number' ? timeout : DEFAULT_TIMEOUT return new Promise<T>((resolve, reject) => { const callbackQuery = typeof param.callbackQuery === 'string' ? param.callbackQuery : 'callback' const callbackName = typeof param.callbackName === 'string' ? param.callbackName : 'jsonp_' + randomStr() param[callbackQuery] = callbackName // Remove callbackQuery and callbackName. delete param.callbackQuery delete param.callbackName // Convert params to querying str. let queryStrs: (string[])[] = [] Object.keys(param).forEach(queryKey => { queryStrs = queryStrs.concat(formatParams(queryKey, param[queryKey])) }) const queryStr = flatten(queryStrs).join('&') const onError = () => { removeErrorListener() clearTimeout(timeoutTimer) reject({ status: 400, statusText: 'Bad Request' }) } const removeErrorListener = () => { paddingScript.removeEventListener('error', onError) } const removeScript = () => { document.body.removeChild(paddingScript) delete window[callbackName] } // Timeout timer. let timeoutTimer = null // Setup timeout. if (timeout > -1) { timeoutTimer = setTimeout(() => { removeErrorListener() removeScript() reject({ statusText: 'Request Timeout', status: 408 }) }, timeout) } // Create global function. window[callbackName] = (json: T) => { clearTimeout(timeoutTimer) removeErrorListener() removeScript() resolve(json) } // Create script element. const paddingScript = document.createElement('script') // Add error listener. paddingScript.addEventListener('error', onError) // Append to head element. paddingScript.src = url + (/\? /.test(url) ? '&' : '? ') + queryStr document.body.appendChild(paddingScript) }) }Copy the code

The resources

vue-jsonp – npm

vue-jsonp – github