// ==UserScript==
// @name HttpRequest
// @namespace hoehleg.userscripts.private
// @version 0.1
// @description HttpRequest for any type of request and HttpRequestHTML to request webpage. Supports caching of responses to handle status 304.
// @author Gerrit Höhle
//
// @grant GM_xmlhttpRequest
//
// @require https://greasyfork.org/scripts/405143-simplecache/code/SimpleCache.js
// @require https://greasyfork.org/scripts/405144-httprequest/code/HttpRequest.js
//
// @require https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js
//
// ==/UserScript==
/* jshint esnext: true */
/* globals globals $, jQuery, SimpleCache */
const HttpRequest = (() => {
const responsesCache = new SimpleCache({ keyExtractor: (httpRequest) => [ httpRequest.method, httpRequest.url, httpRequest.headers, httpRequest.data, httpRequest.params ].join() });
const urlWithParams = (url, paramsObject) => {
const params = Object.entries(paramsObject).map(([key, value]) => key + '=' + value).join('&');
return (url.length > 0) ? url + '?' + params : params;
};
return class HttpRequest {
constructor({ method, url = window.location.href, onLoad = () => {}, onError = () => {}, headers = '', data = '', keepInCacheTimoutMs = 10 * 60000, params = {} } = {}) {
Object.assign(this, { method, url, onLoad, onError, headers, data, keepInCacheTimoutMs, params });
}
send() {
const method = this.method.toUpperCase();
let url = this.url;
let headers = this.headers;
let data = this.data;
const onload = (response) => {
switch (response.status) {
case 200:
if (this.keepInCacheTimoutMs > 0) {
responsesCache.set(this, response, this.keepInCacheTimoutMs);
}
break;
case 304:
if (this.isCached()) {
response = this.getFromCache();
response.status = 304;
}
break;
default:
this.onError(response);
return;
}
this.onLoad(response);
};
const onerror = this.onError;
switch (method) {
case 'GET':
if (this.params) {
url = urlWithParams(url, this.params);
}
break;
case 'POST':
case 'PUT':
Object.assign(headers, { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' });
if (this.params) {
data = urlWithParams(data, this.params);
}
break;
}
return GM_xmlhttpRequest({ method, url, onload, onerror: this.onError, headers: this.headers, data });
}
isCached() {
return responsesCache.has(this);
}
getFromCache() {
return responsesCache.get(this);
}
};
})();
class HttpRequestHtml extends HttpRequest {
constructor({ url, method = "GET", onSuccess = () => {}, onError, headers, data, keepInCacheTimoutMs } = {}) {
super({ method, url, onError, headers, data, keepInCacheTimoutMs });
Object.defineProperty(this, 'onLoad', {
value: (response) => {
if (response.status == 200) {
response.responseHtml = new DOMParser().parseFromString(response.responseText, 'text/html');
this.onSuccess(response);
}
},
enumerable: true
});
this.onSuccess = onSuccess;
}
}