轻小说文库下载

跨域图片加载

当前为 2021-01-10 提交的版本,查看 最新版本

// ==UserScript==
// @name         轻小说文库下载
// @namespace    wenku8Haoa
// @version      1.3
// @description  跨域图片加载
// @author       HaoaW
// @match        https://www.wenku8.net/*
// @match        http://www.wenku8.net/*
// @connect      dl.wenku8.com
// @connect      picture.wenku8.com
// @connect      img.wenku8.com
// @require      https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.5.1.min.js
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function () {
    'use strict';
    //替换所有
    String.prototype.replaceAll = function (exp, newStr) {
        return this.replace(new RegExp(exp, "gm"), newStr);
    };
    //标记含有html代码的行
    var htmlLine = function (txt) {
        return 'c1ef6520' + txt + '1a5219e9b2b0';
    };
    //格式化内容
    var contentFormat = function (txt) {
        //设置章节名样式
        let txtTmp = txt.replaceAll(/^ {2}\S+.*$/,
            function (match) {
                return htmlLine('<br/><div style="background:#e4e1d8" id="title">' + match.trim() + '</div>');
            }
        );
        txtTmp = $('<div></div>').text(txtTmp).html();
        txtTmp = txtTmp.replaceAll(/ /, '&nbsp;');
        txtTmp = txtTmp.replaceAll(/(c1ef6520).*(1a5219e9b2b0)/,
            function (match) {
                return $('<div></div>').html(match.replaceAll(/(&nbsp;)/, ' ').replace('c1ef6520', '').replace('1a5219e9b2b0', '')).text();
            }
        );
        txtTmp = txtTmp.replaceAll(/[\r\n]+/, '<br/>');
        return txtTmp;
    };
    // 下载图片blob展示,解决跨域问题。
    var imgBlobCreate = function (imgEle, srcURL) {
        GM_xmlhttpRequest({
            method: 'GET',
            url: srcURL,
            responseType: 'blob',
            onload: function (rsp) {
                if (rsp.statusText == "OK") {
                    let rspBlob = rsp.response;
                    let blobSrc = URL.createObjectURL(rspBlob);
                    imgEle.onload = function (evt) {
                        URL.revokeObjectURL(this.src);
                    };
                    imgEle.src = blobSrc;
                }
            },
        });
    };
    //格式化图片
    var imgFormat = function (txt) {
        let imgResultRoot = $('<div></div>');

        let imgRoot = $('<div></div>').html(txt);
        $('.divimage', imgRoot).each(function () {
            let jqthis = $(this);
            let imgURL = jqthis.attr('title');//取得图片url
            let itemEle = $('<div class="divimage"><a target="_blank"><img border="0" class="imagecontent" /></a></div>');
            $('a', itemEle).attr('href', imgURL);
            $('img', itemEle).attr('src', imgURL);

            imgResultRoot.append(itemEle);
        });

        return imgResultRoot.html();
    }

    //格式化从pack.php下载的带有Html的内容
    var htmlFormat = function (htmlStr) {
        let resultRoot = $('<div></div>');

        let strRoot = $('<div></div>').html(htmlStr);
        $('.chaptertitle', strRoot).each(function () {
            let jqthis = $(this);
            let cTitle = jqthis.text();//取得章节名
            let itemEle = $('<div style="background-color:silver" id="title"></div>');
            itemEle.text(cTitle);
            resultRoot.append(itemEle);
            resultRoot.append('<br />');
            let nextHtml = jqthis.next().html();
            if (-1 != cTitle.indexOf('插图')) {
                nextHtml = imgFormat(nextHtml);
            }
            resultRoot.append(nextHtml);
            resultRoot.append('<br /><br />');
        });

        return resultRoot.html();
    }

    // 检查跨域请求
    var checkUrl = function (url) {
        return new Promise(function (resolve, reject) {
            if (-1 == url.indexOf('.wenku8.')) resolve(false);
            var oReq = new XMLHttpRequest();
            oReq.addEventListener("loadend", function () {
                if (oReq.status == 200)
                    resolve(false)
                else
                    resolve(true)
            });
            oReq.open("HEAD", url);
            oReq.send();
        });
    };

    //使用下载图片blob的方式加载图片
    $('img').each(function () {
        let imgEle = this;
        checkUrl(imgEle.src).then(function (rst) {
            if (rst) {
                imgBlobCreate(imgEle, imgEle.src);
            }
        });
    });

    //目录或内容页面会声明章节变量。
    if ('undefined' == typeof chapter_id || undefined === chapter_id) { }
    else {
        //本书编号 article_id

        //目录页面章节id定义为 '0'
        if ('0' == chapter_id) {//在章节名之后添加下载链接
            //书名
            let aname = $('#title').text();
            //添加全本下载链接
            let allDLink = 'http://dl.wenku8.com/down.php?type=utf8&id=' + article_id + '&fname=' + aname;
            let allaEle = '<a href="' + allDLink + '">&nbsp;&nbsp;全本下载(utf-8)</a>';
            $('#title').append(allaEle);

            $('.vcss').each(function () {
                let jqthis = $(this);
                let vname = jqthis.text();
                let nextChapter = jqthis.parent().next().children().first();
                let vid = $('a', nextChapter).attr('href').split('.')[0];
                //vid = (Number(vid)-1).toString();//部分文章无法使用章节减1来下载,直接使用章节可以下载(下载内容使用-1时章节名包含小说名,不-1不包含小说名)

                let dlink = 'http://dl.wenku8.com/packtxt.php?aid=' + article_id +
                    '&vid=' + vid + '&aname=' + aname + '&vname=' + vname + '&charset=utf-8';
                let aEle = '<a href="' + dlink + '">&nbsp;&nbsp;下载(utf-8)</a>'
                jqthis.append(aEle);
            });
        }
        else {
            if ('0' != chapter_id) {//内容页面
                //如果包含一个内容为 'null'的span则判定为版权限制
                if ($('#contentmain span').first().text().trim() == 'null') {
                    //设置下一页和上一页快捷键到目录页
                    preview_page = next_page = index_page;
                    $('#content').text('正在下载,请稍候...');
                    //下载带有Html标记的内容
                    let dlink = 'http://dl.wenku8.com/pack.php?aid=' + article_id +
                        '&vid=' + chapter_id;
                    GM_xmlhttpRequest({
                        method: 'GET',
                        url: dlink,
                        onload: function (response) {
                            if (response.statusText == "OK") {
                                var formatHtml = htmlFormat(response.responseText);
                                $('#content').html(formatHtml);

                                //使用下载图片blob的方式加载图片
                                $('img').each(function () {
                                    let imgEle = this;
                                    checkUrl(imgEle.src).then(function (rst) {
                                        if (rst) {
                                            imgBlobCreate(imgEle, imgEle.src);
                                        }
                                    });
                                });
                            } else {//html下载可能会失败,使用下载文本的方法来下载
                                if (-1 != $('#title').text().indexOf('插图')) {
                                    $('#content').text('无法获取插图');
                                } else {
                                    dlink = 'http://dl.wenku8.com/packtxt.php?aid=' + article_id +
                                        '&vid=' + chapter_id;
                                    GM_xmlhttpRequest({
                                        method: 'GET',
                                        url: dlink,
                                        onload: function (response) {
                                            if (response.statusText == "OK") {
                                                let formatTxt = contentFormat(response.responseText);
                                                $('#content').html(formatTxt);
                                            } else {
                                                $('#content').text('下载失败');
                                            }
                                        },
                                    });
                                }
                            }
                        },
                    });

                }
            }
        }
    }

    // Your code here...
})();