上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

[油猴脚本开发指南]前后端相结合实现静默下载

[复制链接]
  • TA的每日心情
    慵懒
    11 小时前
  • 签到天数: 811 天

    [LV.10]以坛为家III

    31

    主题

    552

    回帖

    1555

    积分

    荣誉开发者

    积分
    1555

    荣誉开发者新人进步奖油中2周年生态建设者新人报道挑战者 lv2油中3周年喜迎中秋

    发表于 2023-8-21 11:34:06 | 显示全部楼层 | 阅读模式

    本帖最后由 steven026 于 2023-8-21 12:46 编辑

    前言

    环境

    本编指南内容并非纯前端指南,不仅涉及前端脚本猫/油猴脚本,且涉及后端本地服务器。
    本编指南以前端脚本猫、后端Node.js为例,其余前后端原理相通大同小异,自行转换。

    背景

    众所周知,现代前端浏览器出于安全的目的,禁止网页、脚本、插件直接静默下载文件到本地,必须经过用户手动确认。
    但是当我们一次性下载较多或较频繁下载文件时,每次都要单独手动确认实在过于麻烦。
    即使使用JSZip打包文件也只是减少了确认次数,仍需手动确认。
    为了解决静默下载的需求,我们可以引入后端本地服务器,前端静默下载属于越权行为,但在后端并无限制,且只是单纯为了静默下载只需搭建一个简易后端服务器即可,非常方便。


    既然纯前端静默下载属于越权行为无法做到,那么我们为什么不直接用纯后端环境而是使用前后端相结合的方法呢?
    由于纯后端缺少浏览器环境无法轻易下载所有文件,部分文件需要登录、验证、鉴权方可下载,但并非所有登录验证鉴权都可以轻易做到,更多的是需要逆向网站计算出其加密方法,而这一过程实在过于麻烦,不如使用前后端相结合的方式,前端模拟正常用户操作负责正常登录验证下载,而后端负责写入到本地。

    原理

    前端(脚本猫)负责获取文件下载链接并使用GM_xmlhttpRequest(非GM_download)以responseType: "blob"形式下载到本地,并通过GM_xmlhttpRequest直接将blob POST到本地后端服务器
    后端(Node.js) 负责搭建本地服务器接收前端请求,通过Buffer解析请求内容并写入到本地

    建议阅读

    前端API(脚本猫)

    GM_xmlhttpRequest
    https://docs.scriptcat.org/docs/dev/api/#gm_xmlhttprequest-

    后端API(Node.js)

    Http http.createServer/request
    https://nodejs.org/dist/latest-v20.x/docs/api/http.html
    File System fs.writeSync
    https://nodejs.org/dist/latest-v20.x/docs/api/fs.html#fswritesyncfd-buffer-options

    可选指南

    [油猴脚本开发指南]实现前端全自动唤醒本地后端
    https://bbs.tampermonkey.net.cn/thread-4531-1-1.html

    代码

    以下载脚本猫图标为例,
    (GM_xmlhttpRequest可自动填充浏览器环境参数,如无特殊Headers无需填写额外内容)

    脚本猫代码

    GM_xmlhttpRequest({
        // 希望下载的文件路径
        url: 'https://bbs.tampermonkey.net.cn/data/attachment/common/a3/common_68_icon.png',
        method: 'GET',
        // 以blob形式接收文件,可直接转发给后端无需额外操作
        responseType: 'blob',
        onload: (xhr) => {
            console.log(xhr)
            if (xhr.status != 200) throw new Error('response error')
            // 将下载到的blob直接转发给后端
            GM_xmlhttpRequest({
                // 端口与后端保持相同 路径为希望文件存放路径
                url: "http://localhost:1234/test/png/scriptcat.png",
                method: 'POST',
                data: xhr.response,
                onload: (xhr_) => console.log(xhr_)
            })
        }
    })

    Node.js代码

    const http = require('http');
    const fs = require('fs');
    
    // 监听端口
    const port = '1234';
    // 文件保存目录
    const dataDir = 'D:';
    http.createServer(async function (req, res) {
        console.log(req);
        if (req.url == '/' || req.method!='POST') return res.end('invaild path or method');
        // 根据请求url确定文件保存路径
        const fileDir = dataDir + req.url;
    
        const data = [];
        req.on('data', (chunk) => data.push(chunk));
        req.on('end', () => {
            const file = Buffer.concat(data);
            // 写入文件
            fs.writeFileSync(fileDir, file);
        });
        res.end('success ' + fileDir);
    }).listen(port);
    

    效果预览

    全程静默下载,无需额外确认。
    image.png
    image.png

    完结撒花

    咕咕咕

    已有3人评分好评 油猫币 理由
    tfsn20 + 1 + 3 ggnb!
    wwwwwllllk + 1 + 7 ggnb!
    王一之 + 1 + 4 ggnb!

    查看全部评分 总评分:好评 +3  油猫币 +14 

  • TA的每日心情
    开心
    3 小时前
  • 签到天数: 213 天

    [LV.7]常住居民III

    305

    主题

    4188

    回帖

    4055

    积分

    管理员

    积分
    4055

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2023-8-21 11:37:15 | 显示全部楼层
    感觉不能叫 油猴脚本开发指南 了,脚本猫开发指南!
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    11 小时前
  • 签到天数: 811 天

    [LV.10]以坛为家III

    31

    主题

    552

    回帖

    1555

    积分

    荣誉开发者

    积分
    1555

    荣誉开发者新人进步奖油中2周年生态建设者新人报道挑战者 lv2油中3周年喜迎中秋

    发表于 2023-8-21 11:39:42 | 显示全部楼层
    王一之 发表于 2023-8-21 11:37
    感觉不能叫 油猴脚本开发指南 了,脚本猫开发指南!

    脚本猫中文网!
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表