Skrip ini tidak untuk dipasang secara langsung. Ini adalah pustaka skrip lain untuk disertakan dengan direktif meta // @require https://update.greasyfork.org/scripts/405144/1106047/HttpRequest.js
// ==UserScript==
// @name HttpRequest Library
// @namespace hoehleg.userscripts.private
// @version 0.7.1
// @description HttpRequest for any type of request and HttpRequestHTML to request webpage. Supports caching of responses for a given period and paging.
// @author Gerrit Höhle
//
// @grant GM_xmlhttpRequest
//
// ==/UserScript==
// https://greasyfork.org/de/scripts/405144
/* jslint esversion: 9 */
class HttpRequest {
constructor({
method,
url,
params = {},
headers = {},
data = '',
contentType = 'application/x-www-form-urlencoded; charset=UTF-8',
responseType = 'text',
} = {}) {
/** @type {string} */
this.method = method.toUpperCase();
/** @type {string} */
this.url = url;
/** @type {Object<string, string|number>|string} */
this.params = params;
/** @type {object} */
this.headers = headers;
/** @type {string} */
this.data = data;
/** @type {string} */
this.contentType = contentType;
/** @type {string} */
this.responseType = responseType;
}
async send() {
if (!this.method || !this.url) {
return await Promise.reject("invalid request");
}
const { method, responseType } = this;
const params = typeof this.params === "string" ? this.params : Object.entries(this.params).map(([key, value]) => key + '=' + value).join('&');
let url = this.url;
if (params.length) {
url += '?' + params;
}
url = encodeURI(url);
const headers = Object.assign({ 'Content-Type': this.contentType }, this.headers);
const data = typeof this.data === 'string' ? this.data : JSON.stringify(this.data);
return await new Promise((resolve, reject) => {
const onload = (response) => {
resolve(response);
};
const onerror = (errorEvent) => {
console.log(errorEvent);
reject("network error");
};
GM_xmlhttpRequest({ method, url, onload, onerror, headers, data, responseType });
});
}
static async send(...args) {
return await new HttpRequest(...args).send();
}
}
class HttpRequestHtml extends HttpRequest {
/**
* @param {HttpRequestHtmlParams} param0
*/
constructor({
url,
params = {},
pageNr = 0,
pagesMaxCount = 1,
resultTransformer = (resp, _httpRequestHtml) => resp,
hasNextPage = (_resp, _httpRequestHtml, _lastResult) => false,
urlConfiguratorForPageNr = (url, _pageNr) => url,
paramsConfiguratorForPageNr = (params, _pageNr) => params,
} = {}) {
super({ method: 'GET', url, params });
Object.assign(this, {
pageNr,
pagesMaxCount: Math.max(0, pagesMaxCount),
resultTransformer,
hasNextPage,
urlConfiguratorForPageNr,
paramsConfiguratorForPageNr,
});
}
/**
* @returns {Promise<HttpRequestHtmlResponse|object|Array<object>}
*/
async send() {
const results = [];
let response = null, requestForPage = null;
for (let pageNr = this.pageNr; pageNr < this.pageNr + this.pagesMaxCount; pageNr++) {
requestForPage = new HttpRequestHtml({
...this, ...{
url: this.urlConfiguratorForPageNr(this.url, pageNr),
params: this.paramsConfiguratorForPageNr(typeof this.params === 'string' ? this.params : { ...this.params }, pageNr)
}
});
response = await HttpRequest.prototype.send.call(requestForPage);
if (response.status == 200 || response.status == 304) {
response.html = new DOMParser().parseFromString(response.responseText, 'text/html');
}
const resultForPage = this.resultTransformer(response, requestForPage);
results.push(resultForPage);
if (!this.hasNextPage(response, requestForPage, resultForPage)) {
break;
}
}
return this.pagesMaxCount > 1 ? results : results[0];
}
/**
* @param {HttpRequestHtmlParams} param0
* @returns {Promise<HttpRequestHtmlResponse|object|Array<object>}
*/
static async send(...args) {
return await new HttpRequestHtml(...args).send();
}
}
class HttpRequestJSON extends HttpRequest {
/** @param {HttpRequestJSONParams} param0 */
constructor({
method = 'GET',
url,
headers,
data,
params = {},
fallbackResult = null,
contentType = 'application/json',
}) {
super({ method, url, headers, data, params, contentType, responseType: "json" });
this.fallbackResult = fallbackResult;
}
/** @returns {Promise<any>} */
async send() {
const response = await super.send();
if (!response || !response.responseText) {
return this.fallbackResult;
}
try {
return JSON.parse(response.responseText);
} catch (error) {
console.log(error);
return this.fallbackResult;
}
}
/**
*
* @param {HttpRequestJSONParams} param0
* @returns {Promise<any>}
*/
static async send(param0) {
return await new HttpRequestJSON(param0).send();
}
}
class HttpRequestBlob extends HttpRequest {
constructor({
method = 'GET',
url,
headers,
data,
params = {},
contentType,
}) {
super({ method, url, headers, data, params, contentType, responseType: 'blob' });
}
async send() {
const response = await super.send();
/** @type {Blob} */
const blob = response.response;
const data = await new Promise((resolve, reject) => {
const reader = Object.assign(new FileReader(), {
onload: (load) => {
resolve(load.target.result);
},
onerror: (error) => {
console.log(error);
reject(reader.result);
}
});
reader.readAsDataURL(blob);
});
return data;
}
static async send(param0) {
return await new HttpRequestBlob(param0).send();
}
}