Greasy Fork

今日优读

主要搭建一个知识平台以及读书辅助工具,提供书籍搜索,中图分类和学科搜索。

目前为 2021-10-13 提交的版本。查看 最新版本

// ==UserScript==
// @name           今日优读
// @description    主要搭建一个知识平台以及读书辅助工具,提供书籍搜索,中图分类和学科搜索。
// @author         018([email protected])
// @contributor    Rhilip
// @connect        *
// @grant          GM_xmlhttpRequest
// @require        https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @require https://greasyfork.org/scripts/32927-md5-hash/code/MD5%20Hash.js?version=225078
// @include        http://uread.today/*
// @include        http://127.0.0.1:9090/*
// @include        http://book.ucdrs.superlib.net/views/specific/*
// @include        http://product.dangdang.com/*
// @include        https://item.jd.com/*
// @include        https://book.douban.com/subject/*
// @include        https://kns.cnki.net/*
// @include        https://ct.istic.ac.cn/*
// @include        https://weread.qq.com/*
// @include        https://yabook.org/*
// @include        https://yabook.blog/*
// @include        https://www.jiumodiary.com/*
// @include        http://www.ncpssd.org/*
// @version        0.3.0
// @icon           http://uread.today/static/img/favicon.ico
// @run-at         document-end
// @namespace      http://uread.today
// ==/UserScript==

// This Userscirpt can't run under Greasemonkey 4.x platform
if (typeof GM_xmlhttpRequest === 'undefined') {
    alert('不支持Greasemonkey 4.x,请换用暴力猴或Tampermonkey')
    return
}

;(function () {
    'use strict';

    $(document).ready(function () {
        if (location.href.includes('http://book.ucdrs.superlib.net/views/specific')) {
            addViewOrEmbody('.tubox dl', '.tutilte');
        } else if (location.href.includes('http://product.dangdang.com')) {
            addViewOrEmbody('#detail_describe', '.name_info h1');
        } else if (location.href.includes('https://item.jd.com')) {
            addViewOrEmbody('.p-parameter-list', '.sku-name');
        } else if (location.href.includes('https://book.douban.com/subject')) {
            addViewOrEmbody('#info', '#wrapper > h1 > span');
        } else if (location.href.includes('https://kns.cnki.net/kns8/defaultresult/index')) {
            handleCNKI();
        } else if (location.href.includes('https://ct.istic.ac.cn/site/organize/word')) {
            handleIstic();
        } else if (location.href.includes('https://weread.qq.com/')) {
            handleWeread();
        } else if (location.href.includes('https://yabook.')) {
            handleYabook();
        } else if (location.href.includes('https://www.jiumodiary.com/')) {
            handleJiumodiary();
        } else if (location.href.includes('http://www.ncpssd.org/index.aspx')) {
            handleNcpssd();
        } else if (location.href.includes('http://uread.today/')) {
            handleuRead();
        } else if (location.href.includes('http://127.0.0.1:9090/')) {
            handleuRead();
        }
    })

    function addViewOrEmbody(isbnselecter, titleselecter) {
        let match = document.querySelector(isbnselecter).innerText.match(/ISBN.*/)
        if (match) {
            let isbn = match[0].replace(/\D/g, '');
            doGet('http://api.uread.today/master/anon/book/get?isbn=' + isbn, {isbn: isbn}, function(ret, responseDetail, meta) {
                if (ret && ret.resultcode === 1) {
                    $(titleselecter).append('<a target="_blank" href="http://uread.today/book?doi=' + ret.data + '" style="margin-left: 20px !important"><img title="查看" width="15px" src="data:image/jpeg;base64,/9j/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAgICAgICAgICAgMDAwMDAwMDAwMBAQEBAQEBAgEBAgICAQICAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA//dAAQAAv/uAA5BZG9iZQBkwAAAAAH/wAARCAAPAA8DABEAAREBAhEB/8QAbAABAQEAAAAAAAAAAAAAAAAACAkKAQEBAQAAAAAAAAAAAAAAAAAFBgQQAAEFAAIDAQEAAAAAAAAAAAUCAwQGBwEICRESEyIRAAICAgEDBAIDAAAAAAAAAAECAxEEBSESEzEABiJBFBUyUXH/2gAMAwAAARECEQA/ANNvm77NTOtHUMNO+XBgHS9goVGslyZuJCkSqyOFyZOk8xBhcRHlFeSVuTQli/hpvn3DkSPf9fHHNL7Y1eDtcuSLOyvxQkJZWpWJawvh6U0CSQSOBf1RN2+xzdTrptjrtadxnQxsyYQmXGOSwHEQyHKpEx8qzkKzAISOsEVVza8D9LoFOv4tthiFb66KPNw45oDY0DnSERp6UJcOVYmZrZSUJlqXGedgy5MVTzSvzcWn0rmemjEUrRg9QViLoiwPBo8gHyL59a8WWWbGjmnjMM7opaMlWKMQCUZkLIWU/ElGZSQelmFE/wD/0HB526b3G7jGcspNj69RMko+I2bRTIQ4F7DVXSoGgyTMULHrJktnkuvZy3WjbMYKthmTyRIuQIxaY3wlfClfdp7f/W4/UZJj81Bvtm1K8hf5chjwTxVA0ar0Pu591jYAm0GJDm7LvxL2pZzjp2WcLPL3RFN84YyZEj7dTMvbLx31hU+FU524wzND+JBuklNgZwc0MtoabKz2jrAxusqmZ1Ta48OFZwMzsoJRyesNKWRIOwpQ5qQTMS5rkdT7j7j523jw5ZTO0xElVXQT9k+bHi6FjwB/gXIVXKxnqjs0TwSPokc0SPqzX9n1/9k="></a>');
                } else {
                    $(titleselecter).append('<a target="_blank" href="http://uread.today/embody?isbn=' + meta.isbn + '" style="margin-left: 20px !important"><img title="收录" width="15px" src="data:image/jpeg;base64,/9j/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAgICAgICAgICAgMDAwMDAwMDAwMBAQEBAQEBAgEBAgICAQICAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA//dAAQAAv/uAA5BZG9iZQBkwAAAAAH/wAARCAAPAA8DABEAAREBAhEB/8QAbAABAQEAAAAAAAAAAAAAAAAACAkKAQEBAQAAAAAAAAAAAAAAAAAFBgQQAAEFAAIDAQEAAAAAAAAAAAUCAwQGBwEICRESEyIRAAICAgEDBAIDAAAAAAAAAAECAxEEBSESEzEABiJBFBUyUXH/2gAMAwAAARECEQA/ANNvm77NTOtHUMNO+XBgHS9goVGslyZuJCkSqyOFyZOk8xBhcRHlFeSVuTQli/hpvn3DkSPf9fHHNL7Y1eDtcuSLOyvxQkJZWpWJawvh6U0CSQSOBf1RN2+xzdTrptjrtadxnQxsyYQmXGOSwHEQyHKpEx8qzkKzAISOsEVVza8D9LoFOv4tthiFb66KPNw45oDY0DnSERp6UJcOVYmZrZSUJlqXGedgy5MVTzSvzcWn0rmemjEUrRg9QViLoiwPBo8gHyL59a8WWWbGjmnjMM7opaMlWKMQCUZkLIWU/ElGZSQelmFE/wD/0HB526b3G7jGcspNj69RMko+I2bRTIQ4F7DVXSoGgyTMULHrJktnkuvZy3WjbMYKthmTyRIuQIxaY3wlfClfdp7f/W4/UZJj81Bvtm1K8hf5chjwTxVA0ar0Pu591jYAm0GJDm7LvxL2pZzjp2WcLPL3RFN84YyZEj7dTMvbLx31hU+FU524wzND+JBuklNgZwc0MtoabKz2jrAxusqmZ1Ta48OFZwMzsoJRyesNKWRIOwpQ5qQTMS5rkdT7j7j523jw5ZTO0xElVXQT9k+bHi6FjwB/gXIVXKxnqjs0TwSPokc0SPqzX9n1/9k="></a>');
                }
            }, function(err, meta) {
                console.warn(err)
            });
        }
    }

    function similar(s, t) {
        if (!s || !t) {
            return 0
        }
        var l = s.length > t.length ? s.length : t.length
        var n = s.length
        var m = t.length
        var d = []
        var min = function(a, b, c) {
            return a < b ? (a < c ? a : c) : (b < c ? b : c)
        }
        var i, j, si, tj, cost
        if (n === 0) return m
        if (m === 0) return n
        for (i = 0; i <= n; i++) {
            d[i] = []
            d[i][0] = i
        }
        for (j = 0; j <= m; j++) {
            d[0][j] = j
        }
        for (i = 1; i <= n; i++) {
            si = s.charAt(i - 1)
            for (j = 1; j <= m; j++) {
                tj = t.charAt(j - 1)
                if (si === tj) {
                    cost = 0
                } else {
                    cost = 1
                }
                d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost)
            }
        }
        let res = (1 - d[n][m] / l)
        return res
    }

    function handleuRead() {
        // 试读
        $('#tags').parent().after('<tr><td valign="top" width="60px" class="minor-content">试读:</td> <td class="placeholder-color" id="tryread">...</td></tr>')
        var a = $('#superlibnet');
        if (a) {
            loadSrcDoc (a.attr('href'), {}, function (doc, responseDetail, meta) {
                var element = Object.values(doc.scripts).find(element => element.textContent.includes('send_requestajax'))
                if (element) {
                    var pattern = /".*?"/
                    if (pattern.test(element.textContent)) {
                        var url = pattern.exec(element.textContent)[0].replaceAll('"', '');

                        doText ('http://book.ucdrs.superlib.net/' + url, {}, function (responseText, responseDetail, meta) {
                            var htmlText = unescape(responseText.trim());
                            var html = (new DOMParser()).parseFromString(htmlText, 'text/html');
                            var as = '';
                            for(var a of html.querySelectorAll('.link a')) {
                                if (as.length > 0) {
                                    as += '<span> | </span>'
                                }
                                if (a.textContent === '图书馆文献传递') {
                                    as += '<a href="http://book.ucdrs.superlib.net' + a.href.replace('javascript:subtoRefer(true,', '').replace('\'', '').replace(')', '') + '" target="_blank">' + a.textContent + '</a>'
                                } else {
                                    as += '<a href="' + a.href.replace(location.origin, 'http://book.ucdrs.superlib.net') + '" target="_blank">' + a.textContent + '</a>'
                                }
                            }
                            $('#tryread').html(as)

                        }, function (responseDetail, meta) {
                            $('#tryread').html('<div>无</div>')
                        })
                    }
                }
            }, function (responseDetail, meta) {
                $('#tryread').html('<div>发生异常,请刷新重试。</div>')
            })
        } else {
            $('#tryread').html('<div>无</div>')
        }

        // 电子书
        let title = $('#title').text();
        let srctitle = $('#title > span:nth-child(1)').text();
        let isbn = $('#isbn').text();
        $('#ebook').parent().after('<tr><td valign="top" width="60px" class="minor-content">其他:</td> <td class="placeholder-color" id="otherebook"><span id="ZLibrary"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library(...)' +
                                   '</span><span> | </span><span id="libgen"><img width="12px" src="https://libgen.rs/favicon.ico"> Library Genesis(...)</span>' +
                                   '</span><span> | </span><span id="weread"><img width="12px" src="https://weread.qq.com/favicon.ico"> 微信读书(...)</span>' +
                                   '</span><span> | </span><span id="readersteam">互助联盟(...)</span>' +
                                   '</span><span> | </span><span id="LoreFree"><img width="12px" src="https://ebook2.lorefree.com/favicon.ico"> LoreFree(...)</span>' +
                                   '</span><span> | </span><a id="yabook" target="_blank" href="https://yabook.blog/?q=' + title + '" class="link-item"><img width="12px" src="https://yabook.org/favicon.ico"> 雅书搜索</a>' +
                                   '</td></tr>')
        // Z-Library
        loadDoc('https://1lib.us/s/' + isbn, {title: title, isbn: isbn}, function(doc, responseDetail, meta) {
            let found = false;
            for (let a of doc.querySelectorAll('table.resItemTable h3[itemprop=name] a')) {
                //if (a.textContent.includes(meta.title) || meta.title.includes(a.textContent)) {
                if (similar(a.textContent, meta.title) > 0.5) {
                    let url = a.href.replace(location.host, 'b-ok.global').replace('http:', 'https:');
                    found = true;
                    loadDoc(url, {}, function(doc, responseDetail, meta) {
                        let addDownloadedBook = doc.querySelector('.addDownloadedBook');
                        if (addDownloadedBook) {
                            let txt = addDownloadedBook.textContent.match(/\(.*\)/g);
                            url = addDownloadedBook.href.replace(location.host, 'b-ok.global').replace('http:', 'https:');
                            if ($('#ZLibrary').text().includes('(...)')) {
                                $('#ZLibrary').html('<a target="_blank" href="' + url + '"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library' + txt + '</a>');
                            } else {
                                $('#ZLibrary').append('<a target="_blank" href="' + url + '"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library' + txt + '</a>');
                            }
                        } else {
                            $('#ZLibrary').html('<span style="color:#989B9B"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library(暂无资源)</span>');
                        }
                    }, function(err, meta) {
                        $('#ZLibrary').html('<span style="color:#989B9B"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library(暂无资源)</span>');
                    });
                }
            }

            if (!found) {
                $('#ZLibrary').html('<span style="color:#989B9B"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library(暂无资源)</span>');
            }
        }, function(err, meta) {
            $('#ZLibrary').html('<span style="color:#989B9B"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library(暂无资源)</span>');
        });

        // Library Genesis
        loadDoc('https://libgen.rs/search.php?req=' + isbn + '&lg_topic=libgen&open=0&view=simple&res=25&phrase=1&column=identifier', {title: title, isbn: isbn}, function(doc, responseDetail, meta) {
            let tr = doc.querySelector('body > table.c > tbody > tr:nth-child(2)');
            if (tr) {
                let size = tr.querySelector('td:nth-child(8)').textContent;
                let extension = tr.querySelector('td:nth-child(9)').textContent;
                let download = tr.querySelector('td:nth-child(10) a');
                $('#libgen').html('<a target="_blank" href="' + download.href + '"><img width="12px" src="https://libgen.rs/favicon.ico"> Library Genesis(' + extension + ', ' + size + ')</a>');
            } else {
                $('#libgen').html('<span style="color:#989B9B"><img width="12px" src="https://libgen.rs/favicon.ico"> Library Genesis(暂无资源)</span>');
            }
        }, function(err, meta) {
                $('#libgen').html('<span style="color:#989B9B"><img width="12px" src="https://libgen.rs/favicon.ico"> Library Genesis(暂无资源)</span>');
        });

        // 微信读书
        doGet('https://weread.qq.com/web/search/global?keyword=' + title + '&maxIdx=0&fragmentSize=120&count=40', {title: title, isbn: isbn}, function(json, responseDetail, meta) {
            if (json.books && json.books.length > 0) {
                let bookId
                let paring = function (val) {
                    return val.replace(/(/g, '')
                        .replace(/)/g, '')
                        .replace(/【|﹝|〔/g, '')
                        .replace(/】|﹞|〕/g, '')
                        .replace(/ *编|著|译|等|校/g, '')
                        .replace(/翻译/g, '')
                        .replace(/\(审校\)/g, '')
                        .replace(/译校/g, '')
                        .replace(/编译/g, '')
                        .replace(/正校/g, '')
                        .replace(/•|・|▪/g, '')
                        .replace(/\] +/g, '')
                        .replace(/ *· */g, '')
                        .replace(/ /g, '')
                        .replace(/./g, '')
                        .replace(/\. */g, '.')
                }

                let createId = function (bookId) {
                    let str = MD5(bookId, false)
                    let strSub = str.substr(0, 3)

                    let func = function (id) {
                        if (/^\d*$/.test(id)) {
                            for (var len = id['length'], c = [], a = 0; a < len; a += 9) {
                                var b = id['slice'](a, Math.min(a + 9, len))
                                c['push'](parseInt(b)['toString'](16))
                            }
                            return ['3', c]
                        }
                        for (var d = '', i = 0; i < id['length']; i++) {
                            d += id['charCodeAt'](i)['toString'](16)
                        }
                        return ['4', [d]]
                    }

                    let fa = func(bookId)
                    strSub += fa[0],
                        strSub += 2 + str['substr'](str['length'] - 2, 2)
                    for (var m = fa[1], j = 0; j < m.length; j++) {
                        var n = m[j].length.toString(16)
                        1 === n['length'] && (n = '0' + n), strSub += n, strSub += m[j], j < m['length'] - 1 && (strSub += 'g')
                    }
                    return strSub.length < 20 && (strSub += str.substr(0, 20 - strSub.length)), strSub += MD5(strSub, false).substr(0, 3)
                }
                for (let index = 0; index < json.books.length; index++) {
                    const book = json.books[index]

                    var creators = document.querySelectorAll('#author a')
                    if (creators) {
                        for (const creator of creators) {
                            let author = paring(book.bookInfo.author)
                            let lastName = paring(creator.textContent || '')
                            if (lastName && (lastName.startsWith(author) || lastName.endsWith(author) || author.startsWith(lastName) || author.endsWith(lastName))) {
                                bookId = book.bookInfo.bookId
                                break
                            }
                        }
                    }

                    if (bookId) {
                        break
                    }
                }

                if (bookId) {
                    let urlid = createId(bookId)
                    let url = `https://weread.qq.com/web/reader/${urlid}`
                    $('#weread').html('<a target="_blank" href="' + url + '"><img width="12px" src="https://weread.qq.com/favicon.ico"> 微信读书</a>');
                } else {
                    $('#weread').html('<span style="color:#989B9B"><img width="12px" src="https://weread.qq.com/favicon.ico"> 微信读书(暂无资源)</span>');
                }
            } else {
                $('#weread').html('<span style="color:#989B9B"><img width="12px" src="https://weread.qq.com/favicon.ico"> 微信读书(暂无资源)</span>');
            }
        }, function(err, meta) {
            $('#weread').html('<span style="color:#989B9B">互助联盟(暂无资源)</span>');
        });

        // 互助联盟
        loadDoc('https://www.readersteam.com/vip/?aff=readersteam&q=' + isbn, {title: title, isbn: isbn}, function(doc, responseDetail, meta) {
            let a = doc.querySelector('dl.result-list > dt:nth-child(1) a');
            if (a) {
                $('#readersteam').html('<a target="_blank" href="' + a.href.replace(location.origin, 'https://www.readersteam.com/vip') + '">互助联盟(发起互助)</a>');
            } else {
                $('#readersteam').html('<span style="color:#989B9B">互助联盟(暂无资源)</span>');
            }
        }, function(err, meta) {
            $('#readersteam').html('<span style="color:#989B9B">互助联盟(暂无资源)</span>');
        });

        // LoreFree
        let lorefreeurl = 'https://ebook2.lorefree.com/site/index?s=' + srctitle
        loadDoc(lorefreeurl, {title: title, isbn: isbn}, function(doc, responseDetail, meta) {
            let divs = doc.querySelectorAll('div.body-content > div:nth-child(2) div');
            if (divs && divs.length > 0) {
                $('#LoreFree').html('<a target="_blank" href="' + lorefreeurl + '"><img width="12px" src="https://ebook2.lorefree.com/favicon.ico"> LoreFree(' + divs.length + '+)</a>');
            } else {
                $('#LoreFree').html('<span style="color:#989B9B"><img width="12px" src="https://ebook2.lorefree.com/favicon.ico"> LoreFree(暂无资源)</span>');
            }
        }, function(err, meta) {
            $('#LoreFree').html('<span style="color:#989B9B"><img width="12px" src="https://ebook2.lorefree.com/favicon.ico"> LoreFree(暂无资源)</span>');
        });
    }

    function handleCNKI() {
        let q = getQuery(location.search)
        if (q) {
            $('#txt_search').val(decodeURIComponent(q))
            $('.search-btn').click()
        }
    }

    function handleIstic() {
        let q = getQuery(location.search)
        if (q) {
            $('#termname').val(decodeURIComponent(q))
            $('#btn-search').click()
        }
    }

    function handleWeread() {
        let q = getQuery(location.search)
        if (q) {
            setTimeout(() => {
                $('.search_input_text').val(decodeURIComponent(q))
                $('.search_input_right').click()
            }, 2000)
        }
    }

    function handleYabook() {
        let q = getQuery(location.search)
        if (q) {
            $('#bdcsMain').val(decodeURIComponent(q))
            $('.btn').click()
        }
    }

    function handleJiumodiary() {
        let q = getQuery(location.search)
        if (q) {
            $('#SearchWord').val(decodeURIComponent(q))
            $('#SearchButton').click()
        }
    }

    function handleNcpssd() {
        let q = getQuery(location.search)
        if (q) {
            $('#text_search').val(decodeURIComponent(q))
            $('#but_search').click()
        }
    }

    function getQuery(url) {
        if (!url) return false;
        var q = url.match(/[?&]q=([^&#]*)/i);
        if (!q || !q[1]) return false;

        return q[1];
    }

    // 判断,空返回空字符串
    function opt(val) {
        if (!val) return '';

        if (val instanceof Array) {
            if (val.length > 0) {
                return val[0];
            }
        } else {
            return val;
        }
    }

    // 对使用GM_xmlhttpRequest返回的html文本进行处理并返回DOM树
    function page_parser(responseText, src) {
        // 替换一些信息防止图片和页面脚本的加载,同时可能加快页面解析速度
        if (!src) {
            responseText = responseText.replace(/s+src=/ig, ' data-src='); // 图片,部分外源脚本
            responseText = responseText.replace(/<script[^>]*?>[\S\s]*?<\/script>/ig, ''); //页面脚本
        }
        return (new DOMParser()).parseFromString(responseText, 'text/html');
    }

    // 加载网页
    function loadDoc (url, meta, callback, fail) {
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            onload: function (responseDetail) {
                if (responseDetail.status === 200) {
                    let doc = page_parser(responseDetail.responseText, false)
                    callback(doc, responseDetail, meta)
                } else if (fail){
                    fail(responseDetail, meta);
                }
            },
            onerror: function(err) {
                if (fail) {
                    fail(err, meta);
                }
            }
        })
    }

    // 加载网页
    function loadSrcDoc (url, meta, callback, fail) {
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            onload: function (responseDetail) {
                if (responseDetail.status === 200) {
                    let doc = page_parser(responseDetail.responseText, true)
                    callback(doc, responseDetail, meta)
                } else if (fail){
                    fail(responseDetail, meta);
                }
            },
            onerror: function(err) {
                if (fail) {
                    fail(err, meta);
                }
            }
        })
    }

    // get请求
    function doText (url, meta, callback, fail) {
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            onload: function (responseDetail) {
                if (responseDetail.status === 200) {
                    callback(responseDetail.responseText, responseDetail, meta)
                } else if (fail){
                    fail(responseDetail, meta);
                }
            },
            onerror: function(err) {
                if (fail) {
                    fail(err, meta);
                }
            }
        })
    }

    // get请求
    function doGet (url, meta, callback, fail) {
        GM_xmlhttpRequest({
            method: 'GET',
            url: url,
            onload: function (responseDetail) {
                if (responseDetail.status === 200) {
                    callback(JSON.parse(responseDetail.responseText), responseDetail, meta)
                } else if (fail){
                    fail(responseDetail, meta);
                }
            },
            onerror: function(err) {
                if (fail) {
                    fail(err, meta);
                }
            }
        })
    }

    // post请求
    function doPost (url, headers, data, meta, callback, fail) {
        GM_xmlhttpRequest({
            method: "POST",
            url: url,
            data: data,
            headers: headers,
            onload: function(responseDetail){
                if (responseDetail.status === 200) {
                    callback(JSON.parse(responseDetail.responseText), responseDetail, meta)
                } else if (fail){
                    fail(responseDetail, meta);
                }
            },
            onerror: function(err) {
                if (fail) {
                    fail(err, meta);
                }
            }
        })
    }
})()