FODI,Fast OneDrive Index 的缩写,意为 OneDrive 快速列表,是一款 OneDrive 列表程序。相较于其他程序,此版列表速度极快,且无需服务器,部署极为简单,当然,UI就不那么好看了。
这个教程还是利用Cloudflare Workers部署FODI,无需服务器,但是需要一个OneDrive。前面提过了如何利用cf workers搭建Google Drive,文章如下:
[mark_b]
GoIndex搭建Google Drive目录索引网盘的真香教程
[/mark_b]
1、前言
github:https://github.com/vcheckzen/FODI
功能:
- 接近秒速列表
- 指定展示路径
- 特定文件夹加密
- 无需服务器免费部署
- 基本文本、图片、音视频和 Office 三件套预览
缺点:
- 功能简单,界面简陋
- 不支持巨硬家的 IE 和 UWP 版 EDGE 浏览器
- 可能不支持包含千级数量以上文件的文件夹展示
2、创建 Workers
如果你没有cloudflare的账号的话,需要注册一个,注册就不多说了。登录之后会进入主页,点击靠近右下角的 Workers。
此时系统会建议你修改子域名,直接点击 Set up,随后点击弹出对话框中的 Confirm,之后会进入套餐选择页面,选择免费即可,找到 Continue with free,如图。
这样就创建好了一个workers。
3、上传 FODI 后端
现在进入到workers的工作台,进入到代码编辑页面,复制如下代码到左侧的代码框中。[reply]
/**
* IS_CN: 如果为世纪互联版本,请将 0 改为 1
* EXPOSE_PATH:暴露路径,如全盘展示请留空,否则按 '/媒体/音乐' 的格式填写
* ONEDRIVE_REFRESHTOKEN: refresh_token
*/
const IS_CN = 0;
const EXPOSE_PATH = ""
const ONEDRIVE_REFRESHTOKEN = ""
async function handleRequest(request) {
let requestPath
let querySplited
let queryString = request.url.split('?')[1]
if (queryString) {
querySplited = queryString.split('=')
}
if (querySplited && querySplited[0] === 'file') {
const file = querySplited[1]
const fileName = file.split('/').pop();
requestPath = file.replace('/' + fileName, '')
const url = await fetchFiles(requestPath, fileName)
return Response.redirect(url, 302)
} else {
const { headers } = request
const contentType = headers.get('content-type')
let body={}
if (contentType && contentType.includes('form')) {
const formData = await request.formData()
for (let entry of formData.entries()) {
body[entry[0]] = entry[1]
}
}
requestPath = body ? body['?path'] : '';
const files = await fetchFiles(requestPath, null, body.passwd);
return new Response(files, {
headers: {
'content-type': 'application/json; charset=utf-8',
'Access-Control-Allow-Origin': '*'
}
})
}
}
addEventListener('fetch', event => {
return event.respondWith(handleRequest(event.request))
})
const clientId = [
'4da3e7f2-bf6d-467c-aaf0-578078f0bf7c',
'04c3ca0b-8d07-4773-85ad-98b037d25631'
]
const clientSecret = [
'7/+ykq2xkfx:.DWjacuIRojIaaWL0QI6',
'h8@B7kFVOmj0+8HKBWeNTgl@pU/z4yLB'
]
const oauthHost = [
'https://login.microsoftonline.com',
'https://login.partner.microsoftonline.cn'
]
const apiHost = [
'https://graph.microsoft.com',
'https://microsoftgraph.chinacloudapi.cn'
]
const OAUTH = {
'redirectUri': 'https://scfonedrive.github.io',
'refreshToken': ONEDRIVE_REFRESHTOKEN,
'clientId': clientId[IS_CN],
'clientSecret': clientSecret[IS_CN],
'oauthUrl': oauthHost[IS_CN] + '/common/oauth2/v2.0/',
'apiUrl': apiHost[IS_CN] + '/v1.0/me/drive/root',
'scope': apiHost[IS_CN] + '/Files.ReadWrite.All offline_access'
}
async function gatherResponse(response) {
const { headers } = response
const contentType = headers.get('content-type')
if (contentType.includes('application/json')) {
return await response.json()
} else if (contentType.includes('application/text')) {
return await response.text()
} else if (contentType.includes('text/html')) {
return await response.text()
} else {
return await response.text()
}
}
async function getContent(url) {
const response = await fetch(url)
const result = await gatherResponse(response)
return result
}
async function getContentWithHeaders(url, headers) {
const response = await fetch(url, { headers: headers })
const result = await gatherResponse(response)
return result
}
async function fetchFormData(url, data) {
const formdata = new FormData();
for (const key in data) {
if (data.hasOwnProperty(key)) {
formdata.append(key, data[key])
}
}
const requestOptions = {
method: 'POST',
body: formdata
};
const response = await fetch(url, requestOptions)
const result = await gatherResponse(response)
return result
}
async function fetchAccessToken() {
url = OAUTH['oauthUrl'] + 'token'
data = {
'client_id': OAUTH['clientId'],
'client_secret': OAUTH['clientSecret'],
'grant_type': 'refresh_token',
'requested_token_use': 'on_behalf_of',
'refresh_token': OAUTH['refreshToken']
}
const result = await fetchFormData(url, data)
return result.access_token
}
async function fetchFiles(path, fileName, passwd) {
if (!path || path === '/') {
if (EXPOSE_PATH === '') {
path = ''
} else {
path = ':' + EXPOSE_PATH
}
} else {
if (EXPOSE_PATH === '') {
path = ':' + path
} else {
path = ':' + EXPOSE_PATH + path
}
}
const accessToken = await fetchAccessToken()
const uri = OAUTH.apiUrl + encodeURI(path) + '?expand=children(select=name,size,parentReference,lastModifiedDateTime,@microsoft.graph.downloadUrl)'
const body = await getContentWithHeaders(uri, {
Authorization: 'Bearer ' + accessToken
})
if (fileName) {
let thisFile = null
body.children.forEach(file => {
if (file.name === decodeURIComponent(fileName)) {
thisFile = file['@microsoft.graph.downloadUrl']
return
}
})
return thisFile
} else {
let files = []
let encrypted = false
for (let i = 0; i < body.children.length; i++) {
const file = body.children[i]
if (file.name === '.password') {
const PASSWD = await getContent(file['@microsoft.graph.downloadUrl'])
if (PASSWD !== passwd) {
encrypted = true;
break
} else {
continue
}
}
files.push({
name: file.name,
size: file.size,
time: file.lastModifiedDateTime,
url: file['@microsoft.graph.downloadUrl']
})
}
let parent
if (body.children.length) {
parent = body.children[0].parentReference.path
} else {
parent = body.parentReference.path
}
parent = parent.split(':').pop().replace(EXPOSE_PATH, '') || '/'
parent = decodeURIComponent(parent)
if (encrypted) {
return JSON.stringify({ parent: parent, files: [], encrypted: true })
} else {
return JSON.stringify({ parent: parent, files: files })
}
}
}
[/reply]
不会放,看截图:
注意:
- IS_CN: 如果为世纪互联版本,请将 0 改为 1
- EXPOSE_PATH:暴露路径,如全盘展示请留空,否则按 ‘/媒体/音乐’ 的格式填写
- ONEDRIVE_REFRESHTOKEN: refresh_token
- 至于如何获取refresh_token 看下面的获取方法。
- 预览看到类似图片左侧的数据显示,表示安装成功,之后,我们设置 一个前端,即可展示列表了。如何设置前端,依然要接着往下看。
4、获取 refresh_token
进入 ( 该网址)点击其中的 Get a refresh_token,在打开的微软账号登录页面中,填写你的 OneDrive 账号和密码,完成登录。
登录完毕后浏览器将跳转回上面的页面,此时修改网址,从左往右找到第一个 ?,将其 删除。再找到第一个 &,将其改为 ?,注意要使用英文输入法。下面是修改前后的网址对比:
https://.../?authorization_code&code=... https://.../authorization_code?code=...
修改完毕后直接回车,稍等片刻页面将返回 refresh_token,复制到代码的“refresh_token”中。
5、通过 Github Pages 部署前端
前端仅是一个 HTML 文件,可放到任意静态服务器,此处通过 Github Pages 部署,部署完成后可通过 username.github.io 打开你的网盘。
注册并登录 Github,随后打开 该仓库,点击靠近右上角的 Fork。
稍等片刻,打开“front-end”中的 index.html。然后点击靠近 右上角 的 铅笔 按钮,编辑该文件。如图:
注意:
- SCF_GATEWAY:这里填写你cf workers的分配地址。
- SITE_NAME:站点名称随便填写。
看图:
填写完毕后点击靠近页面最下方的 Commit changes
点击靠近页面右上角的 Settings,将 Repository name 改成 你的 Github 用户名.github.io,随后点击 Rename。
下拉该页面,找到 Github Pages,将 Source 下拉框的值改成 master branch,如果没有则无需修改。
现在,就可以通过 你的 Github 用户名.github.io 访问网盘了。
6、宝塔设置前端
如果你有自己的服务器,可以在安装宝塔面板之后,新建网站,绑定好域名。然后下载程序到自己的网站根目录。
解压之后把“FODI-master/front-end”下面的“index.html”文件,拷贝到网站根目录,之后打开编辑,和第5的方法一样,如下:
保存,即可打开访问,效果如图:
7、最后
虽然界面简陋,但是功能还不错,打开速度快。支持基本文本、图片、音视频和 Office 三件套预览。可能不支持包含千级数量以上文件的文件夹展示,不支持巨硬家的 IE 和 UWP 版 EDGE 浏览器!
推荐在自己的服务器上部署前端,就是一个网页而已,绝对轻量级了。很多人不知道怎么获取 token,可以通过下面URL登录。
国际版, 个人版(家庭版)
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=78d4dc35-7e46-42c6-9023-2d39314433a5&response_type=code&redirect_uri=http://localhost/onedrive-login&response_mode=query&scope=offline_access%20User.Read%20Files.ReadWrite.All
中国版(世纪互联)
https://login.chinacloudapi.cn/common/oauth2/v2.0/authorize?client_id=dfe36e60-6133-48cf-869f-4d15b8354769&response_type=code&redirect_uri=http://localhost/onedrive-login&response_mode=query&scope=offline_access%20User.Read%20Files.ReadWrite.All































