feat: schemaApi 支持 jsonp (#3041)

This commit is contained in:
Allen 2021-11-24 15:22:51 +08:00 committed by GitHub
parent 95f798d606
commit 7d4258d4db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 6 deletions

View File

@ -490,7 +490,7 @@ export interface SchemaApiObject {
/** /**
* API * API
*/ */
method?: 'get' | 'post' | 'put' | 'delete' | 'patch'; method?: 'get' | 'post' | 'put' | 'delete' | 'patch' | 'jsonp';
/** /**
* API * API

View File

@ -148,7 +148,7 @@ export interface RenderOptions {
export interface fetcherConfig { export interface fetcherConfig {
url: string; url: string;
method?: 'get' | 'post' | 'put' | 'patch' | 'delete'; method?: 'get' | 'post' | 'put' | 'patch' | 'delete' | 'jsonp';
data?: any; data?: any;
config?: any; config?: any;
} }

View File

@ -31,7 +31,7 @@ export interface fetcherResult {
} }
export interface fetchOptions { export interface fetchOptions {
method?: 'get' | 'post' | 'put' | 'patch' | 'delete'; method?: 'get' | 'post' | 'put' | 'patch' | 'delete' | 'jsonp';
successMessage?: string; successMessage?: string;
errorMessage?: string; errorMessage?: string;
autoAppend?: boolean; autoAppend?: boolean;

View File

@ -11,11 +11,12 @@ import {
qsstringify, qsstringify,
cloneObject, cloneObject,
createObject, createObject,
qsparse qsparse,
uuid
} from './helper'; } from './helper';
import isPlainObject from 'lodash/isPlainObject'; import isPlainObject from 'lodash/isPlainObject';
const rSchema = /(?:^|raw\:)(get|post|put|delete|patch|options|head):/i; const rSchema = /(?:^|raw\:)(get|post|put|delete|patch|options|head|jsonp):/i;
interface ApiCacheConfig extends ApiObject { interface ApiCacheConfig extends ApiObject {
cachedPromise: Promise<any>; cachedPromise: Promise<any>;
@ -125,7 +126,7 @@ export function buildApi(
} }
// get 类请求,把 data 附带到 url 上。 // get 类请求,把 data 附带到 url 上。
if (api.method === 'get') { if (api.method === 'get' || api.method === 'jsonp') {
if (!~raw.indexOf('$') && !api.data && autoAppend) { if (!~raw.indexOf('$') && !api.data && autoAppend) {
api.query = api.data = data; api.query = api.data = data;
} else if ( } else if (
@ -320,6 +321,10 @@ export function wrapFetcher(
api.data api.data
); );
if (api.method?.toLocaleLowerCase() === 'jsonp') {
return wrapAdaptor(jsonpFetcher(api), api);
}
if (typeof api.cache === 'number' && api.cache > 0) { if (typeof api.cache === 'number' && api.cache > 0) {
const apiCache = getApiCache(api); const apiCache = getApiCache(api);
return wrapAdaptor( return wrapAdaptor(
@ -362,6 +367,71 @@ export function wrapAdaptor(promise: Promise<fetcherResult>, api: ApiObject) {
: promise.then(ret => responseAdaptor(ret, api)); : promise.then(ret => responseAdaptor(ret, api));
} }
export function jsonpFetcher(api: ApiObject): Promise<fetcherResult> {
return new Promise((resolve, reject) => {
let script: HTMLScriptElement | null = document.createElement('script');
let src = api.url;
script.async = true;
function remove() {
if (script) {
// @ts-ignore
script.onload = script.onreadystatechange = script.onerror = null;
if (script.parentNode) {
script.parentNode.removeChild(script);
}
script = null;
}
}
const jsonp = api.query?.callback || 'axiosJsonpCallback' + uuid();
const old = (window as any)[jsonp];
(window as any)[jsonp] = function (responseData: any) {
(window as any)[jsonp] = old;
const response = {
data: responseData,
status: 200,
headers: {}
};
resolve(response);
};
const additionalParams: any = {
_: new Date().getTime(),
_callback: jsonp
};
src += (src.indexOf('?') >= 0 ? '&' : '?') + qsstringify(additionalParams);
// @ts-ignore IE 为script.onreadystatechange
script.onload = script.onreadystatechange = function () {
// @ts-ignore
if (!script.readyState || /loaded|complete/.test(script.readyState)) {
remove();
}
};
script.onerror = function () {
remove();
const errResponse = {
status: 0,
headers: {}
};
reject(errResponse);
};
script.src = src;
document.head.appendChild(script);
});
}
export function isApiOutdated( export function isApiOutdated(
prevApi: Api | undefined, prevApi: Api | undefined,
nextApi: Api | undefined, nextApi: Api | undefined,