mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-27 17:16:14 +01:00
refactor: use fetch() throughout, instead of jQuery .ajax()
This commit is contained in:
@@ -37,123 +37,99 @@ function call(options, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function xhr(options, cb) {
|
async function xhr(options, cb) {
|
||||||
/**
|
// Normalize body based on type
|
||||||
* N.B. fetch api is only used when payload is a FormData object!
|
const { url } = options;
|
||||||
*
|
delete options.url;
|
||||||
* This is because the passed-in options are different between fetch/jQuery .ajax()
|
|
||||||
* If we updated the code to use only fetch, it would be a breaking change.
|
|
||||||
*
|
|
||||||
* Prior to v3.3 there was no support for sending in FormData, so the addition of fetch
|
|
||||||
* handling is not breaking.
|
|
||||||
*
|
|
||||||
* Break this for v4 by making everything use fetch api.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Adjust options based on payload type
|
if (options.data && !(options.data instanceof FormData)) {
|
||||||
if (options.payload instanceof FormData) {
|
options.data = JSON.stringify(options.data || {});
|
||||||
const url = options.url;
|
options.headers['content-type'] = 'application/json; charset=utf-8';
|
||||||
options.body = options.payload;
|
|
||||||
delete options.payload;
|
|
||||||
delete options.url;
|
|
||||||
|
|
||||||
// Allow options to be modified by plugins, etc.
|
|
||||||
({ options } = await fireHook('filter:api.fetchOptions', { options }));
|
|
||||||
|
|
||||||
await fetch(url, {
|
|
||||||
...options,
|
|
||||||
}).then(async (res) => {
|
|
||||||
const payload = await res.json();
|
|
||||||
if (Math.floor(res.status / 100) === 2) {
|
|
||||||
cb(null, (
|
|
||||||
payload &&
|
|
||||||
payload.hasOwnProperty('status') &&
|
|
||||||
payload.hasOwnProperty('response') ? payload.response : (payload || {})
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
cb(new Error(payload.status.message));
|
|
||||||
}
|
|
||||||
}).catch(cb);
|
|
||||||
} else {
|
|
||||||
options.data = JSON.stringify(options.payload || {});
|
|
||||||
options.contentType = 'application/json; charset=utf-8';
|
|
||||||
delete options.payload;
|
|
||||||
|
|
||||||
// Allow options to be modified by plugins, etc.
|
|
||||||
({ options } = await fireHook('filter:api.options', { options }));
|
|
||||||
|
|
||||||
$.ajax(options)
|
|
||||||
.done((res) => {
|
|
||||||
cb(null, (
|
|
||||||
res &&
|
|
||||||
res.hasOwnProperty('status') &&
|
|
||||||
res.hasOwnProperty('response') ? res.response : (res || {})
|
|
||||||
));
|
|
||||||
})
|
|
||||||
.fail((ev) => {
|
|
||||||
let errMessage;
|
|
||||||
if (ev.responseJSON) {
|
|
||||||
errMessage = ev.responseJSON.status && ev.responseJSON.status.message ?
|
|
||||||
ev.responseJSON.status.message :
|
|
||||||
ev.responseJSON.error;
|
|
||||||
}
|
|
||||||
|
|
||||||
cb(new Error(errMessage || ev.statusText));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow options to be modified by plugins, etc.
|
||||||
|
({ options } = await fireHook('filter:api.options', { options }));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: pre-v4 backwards compatibility
|
||||||
|
*
|
||||||
|
* This module now passes in "data" to xhr().
|
||||||
|
* This is because the "filter:api.options" hook (and plugins using it) expect "data".
|
||||||
|
* fetch() expects body, so we rename it here.
|
||||||
|
*
|
||||||
|
* In v4, replace all instances of "data" with "body" and record as breaking change.
|
||||||
|
*/
|
||||||
|
if (options.data) {
|
||||||
|
options.body = options.data;
|
||||||
|
delete options.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
await fetch(url, {
|
||||||
|
...options,
|
||||||
|
}).then(async (res) => {
|
||||||
|
const response = await res.json();
|
||||||
|
if (Math.floor(res.status / 100) === 2) {
|
||||||
|
cb(null, (
|
||||||
|
response &&
|
||||||
|
response.hasOwnProperty('status') &&
|
||||||
|
response.hasOwnProperty('response') ? response.response : (response || {})
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
cb(new Error(response.status.message));
|
||||||
|
}
|
||||||
|
}).catch(cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get(route, payload, onSuccess) {
|
export function get(route, data, onSuccess) {
|
||||||
return call({
|
return call({
|
||||||
url: route + (payload && Object.keys(payload).length ? ('?' + $.param(payload)) : ''),
|
url: route + (data && Object.keys(data).length ? ('?' + $.param(data)) : ''),
|
||||||
}, onSuccess);
|
}, onSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function head(route, payload, onSuccess) {
|
export function head(route, data, onSuccess) {
|
||||||
return call({
|
return call({
|
||||||
url: route + (payload && Object.keys(payload).length ? ('?' + $.param(payload)) : ''),
|
url: route + (data && Object.keys(data).length ? ('?' + $.param(data)) : ''),
|
||||||
method: 'head',
|
method: 'head',
|
||||||
}, onSuccess);
|
}, onSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function post(route, payload, onSuccess) {
|
export function post(route, data, onSuccess) {
|
||||||
return call({
|
return call({
|
||||||
url: route,
|
url: route,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
payload,
|
data,
|
||||||
headers: {
|
headers: {
|
||||||
'x-csrf-token': config.csrf_token,
|
'x-csrf-token': config.csrf_token,
|
||||||
},
|
},
|
||||||
}, onSuccess);
|
}, onSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function patch(route, payload, onSuccess) {
|
export function patch(route, data, onSuccess) {
|
||||||
return call({
|
return call({
|
||||||
url: route,
|
url: route,
|
||||||
method: 'patch',
|
method: 'patch',
|
||||||
payload,
|
data,
|
||||||
headers: {
|
headers: {
|
||||||
'x-csrf-token': config.csrf_token,
|
'x-csrf-token': config.csrf_token,
|
||||||
},
|
},
|
||||||
}, onSuccess);
|
}, onSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function put(route, payload, onSuccess) {
|
export function put(route, data, onSuccess) {
|
||||||
return call({
|
return call({
|
||||||
url: route,
|
url: route,
|
||||||
method: 'put',
|
method: 'put',
|
||||||
payload,
|
data,
|
||||||
headers: {
|
headers: {
|
||||||
'x-csrf-token': config.csrf_token,
|
'x-csrf-token': config.csrf_token,
|
||||||
},
|
},
|
||||||
}, onSuccess);
|
}, onSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function del(route, payload, onSuccess) {
|
export function del(route, data, onSuccess) {
|
||||||
return call({
|
return call({
|
||||||
url: route,
|
url: route,
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
data: JSON.stringify(payload),
|
data,
|
||||||
contentType: 'application/json; charset=utf-8',
|
|
||||||
headers: {
|
headers: {
|
||||||
'x-csrf-token': config.csrf_token,
|
'x-csrf-token': config.csrf_token,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user