ych-pumpkin
Version:
122 lines (102 loc) • 3.41 kB
JavaScript
/**
* json 转FormData
*
* @param {object} data 被转数据 如果是FormData 直接返回
* @returns FormData
*
* @date 2016-12-19
*/
// TODO util
const jsonToFormData = (data) => {
if (data instanceof FormData) {
return data;
}
if (typeof data === 'object') {
const formData = new FormData();
for (var key in data) {
if (data[key] instanceof FileList) {
Array.from(data[key]).forEach((file) => {
formData.append(key, file);
});
} else if (data[key] instanceof Array) {
data[key].forEach((file) => {
formData.append(key, file);
});
} else {
formData.append(key, data[key]);
}
}
return formData;
}
return new FormData();
};
// 只支持一层简单json格式的对象
const jsonToUrlEncode = data => Object.entries(data).map(res => (res[1] !== undefined ? `${res[0]}=${window.encodeURIComponent(res[1])}` : '')).join('&');
// 只支持一层简单json格式的对象
function getEncodeUrl(url, data) {
const urlEncode = jsonToUrlEncode(data);
if (url.indexOf('?') > 0) {
return `${url}&${urlEncode}`;
} else if (urlEncode !== '') {
return `${url}?${urlEncode}`;
}
return url;
}
// TODO jsonp
// copy from other
const defaultOptions = {
timeout: 5000,
jsonpCallback: 'callback',
jsonpCallbackFunction: null,
};
function generateCallbackFunction() {
return `jsonp_${Date.now()}_${Math.ceil(Math.random() * 100000)}`;
}
// Known issue: Will throw 'Uncaught ReferenceError: callback_*** is not defined'
// error if request timeout
function clearFunction(functionName) {
// IE8 throws an exception when you try to delete a property on window
// http://stackoverflow.com/a/1824228/751089
try {
delete window[functionName];
} catch (e) {
window[functionName] = undefined;
}
}
function removeScript(scriptId) {
const script = document.getElementById(scriptId);
document.getElementsByTagName('head')[0].removeChild(script);
}
function fetchJsonp(_url, options = {}) {
// to avoid param reassign
let url = _url;
const timeout = options.timeout || defaultOptions.timeout;
const jsonpCallback = options.jsonpCallback || defaultOptions.jsonpCallback;
let timeoutId;
return new Promise((resolve, reject) => {
const callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction();
const scriptId = `${jsonpCallback}_${callbackFunction}`;
window[callbackFunction] = (response) => {
resolve({
ok: true,
// keep consistent with fetch API
json: () => Promise.resolve(response),
});
if (timeoutId) clearTimeout(timeoutId);
removeScript(scriptId);
clearFunction(callbackFunction);
};
// Check if the user set their own params, and if not add a ? to start a list of params
url += (url.indexOf('?') === -1) ? '?' : '&';
const jsonpScript = document.createElement('script');
jsonpScript.setAttribute('src', `${url}${jsonpCallback}=${callbackFunction}`);
jsonpScript.id = scriptId;
document.getElementsByTagName('head')[0].appendChild(jsonpScript);
timeoutId = setTimeout(() => {
reject(new Error(`JSONP request to ${_url} timed out`));
clearFunction(callbackFunction);
removeScript(scriptId);
}, timeout);
});
}
export { jsonToFormData, jsonToUrlEncode, getEncodeUrl, fetchJsonp };