Alist快速添加云盘分享存储油猴脚本
- 软件编号:1503
- 点击次数:
- 软件语言:简体中文
- 软件大小:9.25 KB
- 提 取 码 :无需提取码
- 下载权限:免费下载
- 软件售价:免费下载
- 下载次数:1次
Alist快速添加存储脚本介绍
使用Alist添加存储时,如果经常需要手动复制分享ID、文件夹ID,再切换到Alist后台填写相关参数,操作起来还是比较麻烦。尤其是在手机上管理Alist,频繁来回切换页面会更加费劲。
针对这个问题,分享一个简单的Alist快速添加存储Userscript脚本。脚本主要用于阿里云盘分享页面,可以直接读取当前页面中的分享ID和目录ID,然后通过Alist接口创建对应的存储,从而减少手动复制粘贴的步骤。
脚本主要功能
在阿里云盘分享页面增加“创建Alist存储”按钮。
自动获取当前分享页面中的分享ID。
自动获取当前页面对应的根目录ID。
支持填写Alist挂载路径。
支持填写阿里云盘分享密码。
自动登录Alist后台并获取token。
调用Alist管理接口创建存储。
手机端可以配合Via浏览器使用。
Alist快速添加存储脚本使用方法
这个脚本属于油猴(Userscript)类型脚本,使用前需要在支持用户脚本的浏览器或扩展中安装。
添加脚本时,将下面的完整代码复制进去,然后重点修改脚本开头的4个变量,也就是Alist地址、管理员用户名、管理员密码以及阿里云盘的refresh_token。
需要修改的4个变量
const baseUrl = 'http://xxxxxxxx:5244' const adminUser = '管理员用户名' const adminPwd = '管理员密码' const refresh_token = '自行获取云盘的refresh_token'
baseUrl填写自己的Alist访问地址,例如Alist实际运行在其他端口,就需要按照自己的环境进行修改。
adminUser和adminPwd填写Alist管理员账号和密码,脚本会通过Alist登录接口获取Token,用于后续创建存储。
refresh_token则需要替换成自己的阿里云盘Refresh Token。原脚本说明中提到可以通过MT管理器查看相关日志获取,具体获取方式建议根据自己当前使用的环境确认。
具体使用流程
完成脚本配置后,打开阿里云盘对应的分享页面。如果脚本正常运行,页面下方会出现一个“创建Alist存储”按钮。
点击按钮后会弹出操作窗口,可以填写Alist挂载路径以及分享密码。脚本会根据当前页面URL自动读取分享ID和根目录ID。
确认无误后点击“确认”,脚本会调用Alist的存储创建接口。如果接口返回成功,页面会提示“创建成功”。
操作过程
配置脚本前面的4个变量。
在支持Userscript的浏览器中安装脚本。
打开阿里云盘分享页面。
点击“创建Alist存储”。
填写Alist挂载路径。
如果分享链接设置了密码,填写分享密码。
点击“确认”。
等待脚本调用Alist接口创建存储。
完整脚本代码
下面是完整的Alist快速添加存储脚本。使用时直接复制,然后按照上面的说明修改开头的4个变量即可。
// ==UserScript==
// @name 快速上传Alist
// @namespace http://tampermonkey.net/
// @version 0.1
// @description 简单就完了
// @AuThor 52pojie
// @match *://*.aliyundrive.com/*
// @Icon https://www.google.com/s2/favicons?sz=64&domain=aliyundrive.com
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @grant GM_log
// @grant GM_getValue
// @grant GM_setValue
// @connect *
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
const baseUrl = 'http://xxxxxxxx:5244'
const adminUser = '管理员用户名'
const adminPwd = '管理员密码'
const refresh_token = '自行获取云盘的refresh_token(可以通过mt管理器查看日志)'
const headerPost = async (url, data, headers, type) => {
return new Promise((resolve, reject) => {
let option = {
method: "POST",
url: url,
headers: headers,
data: data,
responseType: type || 'json',
onload: (res) => {
if (type === 'blob') {
resolve(res)
} else {
const _re = res.response || res
.responseText
typeof _re === 'string' ? resolve(JSON.parse(_re)) : resolve(_re)
}
},
onerror: (err) => {
reject(err);
},
}
try {
let req = GM_xmlhttpRequest(option);
} catch (error) {
console.error(error);
}
});
};
async function addStorage({mount_path, share_id, share_pwd = "", root_folder_id = "root", order_by = "", order_direction = ""}){
return await headerPost(baseUrl + '/api/admin/storage/create',JSON.stringify({
mount_path: mount_path,
order: 0,
remark: '',
cache_expiration: 30,
web_proxy: false,
webdav_policy: "302_redirect",
down_proxy_url: "",
extract_folder: "",
driver: "AliyundriveShare",
addition: JSON.stringify({
refresh_token: refresh_token,
share_id,
share_pwd,
root_folder_id,
order_by,
order_direction
})
}), {
"Authorization": GM_getValue('token'),
"Content-Type": "application/json;charset=UTF-8"
})
};
async function login() {
const res = await headerPost(baseUrl + '/api/auth/login', JSON.stringify({username: adminUser, password: adminPwd, "otp_code":""}), {"Content-Type": "application/json;charset=UTF-8"})
if (res.code === 200) {
GM_setValue('token', res.data.token)
} else {
toast("登录失败")
}
}
function toast(msg) {
const t = (() => {
if (document.querySelector('#J_single_toast')) {
return document.querySelector('#J_single_toast')
} else {
const _t = document.createElement('div')
_t.id = 'J_single_toast'
document.body.appendChild(_t)
return _t
}
})()
t.innerText = msg
t.classList.toggle('show')
setTimeout(() => {t.classList.toggle('show')}, 1500)
}
function createCustomDom() {
let mount_path = `/xx云盘分享_${+new Date}`
const cBtn = document.createElement('div')
cBtn.innerText = "创建Alist存储"
cBtn.className = "cBtn"
document.body.appendChild(cBtn)
const dialog = document.createElement('div')
dialog.className = "mount-path-dialog"
dialog.innerHTML = `
<div class="mask"></div>
<div class="input-wrap">
<div class="input-item">
<p>请输入Alist挂载路径:</p>
<input name="mount_path" value=${mount_path}>
</div>
<div class="input-item">
<p>请输入分享密码:</p>
<input name="share_pwd">
</div>
<div class="btn-group">
<div class="cancel btn">取消</div>
<div class="confirm btn">确认</div>
</div>
</div>`
document.body.appendChild(dialog)
cBtn.addEventListener('click', () => {
dialog.style.display = 'block';
dialog.querySelector('[name="mount_path"]').focus();
dialog.querySelector('[name="mount_path"]').setSelectionRange(1, 999);
})
dialog.addEventListener('click', function(e){
if (Array.from(dialog.querySelectorAll('.mask, .cancel')).includes(e.target)) {
closeDialog()
}
if (e.target === dialog.querySelector('.confirm')) {
const arr = window.location.pathname.split('/')
addStorage({
mount_path: dialog.querySelector('[name="mount_path"]').value,
share_pwd: dialog.querySelector('[name="share_pwd"]').value,
share_id: arr[2],
root_folder_id: arr[4]
}).then(res => {
if (res.code === 200) {
dialog.style.display = 'none'
toast('创建成功')
} else {
toast(res.message)
}
})
}
})
function closeDialog() {
dialog.style.display = 'none'
}
}
async function init() {
GM_addStyle(`
#J_single_toast {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1001;
display: none;
background: rgba(0,0,0,0.8);
color: var(--basic_white);
padding: 10px;
max-width: 300px;
border-radius: 4px;
}
#J_single_toast.show {
display: block;
}
.cBtn {
position: fixed;
left: 50%;
transform: translateX(-50%);
bottom: 80px;
z-index: 999;
bottom: calc(constant(safe-area-inset-bottom) + 80px);
bottom: calc(env(safe-area-inset-bottom) + 80px);
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--basic_white);
background: var(--theme_primary);
height: 44px;
padding: 0 16px;
font-size: 16px;
border-radius: 22px;
}
.mount-path-dialog {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1000;
display: none;
margin: auto;
}
.mount-path-dialog .mask {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(0,0,0,0.6)
}
.mount-path-dialog .input-wrap {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 300px;
height: 280px;
background: #fff;
border-radius: 10px;
box-sizing: boder-box;
}
.mount-path-dialog .input-wrap .input-item {
margin-bottom: 8px;
}
.mount-path-dialog .input-wrap p {
font-size: 14px;
margin-bottom: 5px;
}
.mount-path-dialog .input-wrap input{
display: block;
width: 240px;
height: 40px;
margin: 0 auto 15px;
font-size: 12px;
border: 1px solid #ccc;
padding-left: 8px;
border-radius: 4px;
}
.mount-path-dialog .input-wrap .btn-group {
display: flex;
align-items: center;
justify-content: space-between;
width: 260px;
margin: 0 auto;
}
.mount-path-dialog .input-wrap .btn-group .btn {
display: inline-flex;
align-items: center;
justify-content: center;
flex: 1;
margin: 0 10px;
height: 40px;
background: var(--theme_primary);
color: var(--basic_white);
font-size: 16px;
border-radius: 4px;
}
.mount-path-dialog .input-wrap .btn-group .cancel {
background: #fff;
color: #333;
border: 1px solid #ccc;
}
`)
await login()
createCustomDom()
}
window.addEventListener ("load", init);
})();使用安全注意事项
这个脚本需要填写Alist管理员账号、管理员密码以及阿里云盘的refresh_token,这些信息都属于比较敏感的凭据,因此不要把填写完成后的脚本直接公开分享。
发布脚本时建议保留占位符,让使用者自行填写自己的信息。尤其是refresh_token,不要提交到公开代码仓库,也不要发送给不可信的人。
另外,脚本使用了GM_xmlhttpRequest跨域请求Alist接口,并通过@connect *允许连接任意域名。使用时建议只在自己信任的脚本管理器和浏览器环境中运行,并仔细检查脚本来源。
手机端使用体验
如果平时主要通过手机管理Alist,这种脚本会更加方便。安装好用户脚本后,可以直接在阿里云盘分享页面完成相关操作,不需要频繁在阿里云盘和Alist后台之间切换。
原作者特别提到了Via浏览器,因此手机用户可以根据自己的浏览器脚本支持情况进行测试。不同浏览器对Userscript、GM API以及跨域请求的支持可能存在差异,如果脚本没有正常运行,需要检查浏览器的脚本功能是否开启。
总结
这个Alist快速添加存储脚本属于比较实用的小工具,核心思路就是把原本需要手动完成的分享ID、目录ID复制以及Alist存储创建操作串联起来。
对于经常添加阿里云盘分享存储的Alist用户来说,可以减少重复的复制粘贴和页面切换操作。脚本本身比较简单,主要适合有一定Alist使用经验的用户,根据自己的服务器地址和账号信息进行配置即可。
需要注意的是,Alist版本、接口以及阿里云盘页面结构后续都可能发生变化,因此脚本能否长期正常使用需要以实际环境测试结果为准。
