ITEMS
TIME
SIZE
下载
引用
分享
FODI项目作者github地址(此项目支持cloudflare和腾讯云函数SFC搭建):
https://github.com/vcheckzen/FODI
我的演示地址:
https://cf-onedrive.elle.workers.dev/
为项目添加域名可参考:
https://blog.csdn.net/qq_38243612/article/details/104433673
1、国际版点击获取onedrive的refresh_token,点击Get a refresh token
https://service-36wivxsc-1256127833.ap-hongkong.apigateway.myqcloud.com/release/scf_onedrive_filelistor
2、登录office账号
3、点击接受
4、保存refresh_token内容
5、准备好cloudflare账号,登录以下地址:https://workers.cloudflare.com/,登录后跳转到下图位置,点击workers
6、点击create a worker,第一次使用会让你添加一个后缀,设置后无法修改(格式x.workers.dev)
7、清除下图红色位置代码,粘贴此项目后端代码(下一步骤有代码)。代码地址:
https://github.com/vcheckzen/FODI/blob/master/back-end-cf/index.js
8、将ONEDRIVE_REFRESH_TOKEN 修改为之前保存的refresh_token值,注意在对应的双引号之间,别删了。想要显示特定的目录可填写EXPOSE_PATH 变量,如:/测试文件,想要显示所有,留空即可(如果是世纪互联,还需将IS_CN改为1),保存,记录项目地址。
const IS_CN = 0;
const EXPOSE_PATH = "路径"
const ONEDRIVE_REFRESHTOKEN = "refresh_token"
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 })
}
}
}
9、再新建一个项目(步骤6),并在里面粘贴前端代码,前端代码地址:
https://github.com/ytorpedol/FODI/blob/cf-first-index/cf-first-index.js
这是基于项目作者的代码
https://github.com/vcheckzen/FODI/blob/master/front-end/index.html
修改的,因为我觉得利用github pages来显示前端较为复杂,所以在作者基础上修改成cloudflareworkers支持的代码。
10、修改SCF_GATEWAY:SCF 云函数网关地址和SITE_NAME:站点名称,云函数网关填写第10步保存的项目地址,站点名随便(注意:如果你修改了后端的地址,此处也要进行修改,保证SCF_GATEWAY和后端地址一致就可以了),保存部署,访问前端部署地址看看效果。
async function handleRequest(request) {
const init = {
headers: {
'content-type': 'text/html;charset=UTF-8',
},
}
return new Response(renderHTML(), init);
}
addEventListener('fetch', event => {
return event.respondWith(handleRequest(event.request))
})
function renderHTML() {
return `
Loading...
ITEMS
TIME
SIZE
下载
引用
分享